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 // FIXME: sometimes gets stuck in a loop routing the last few nets
12 // FEATURE: ability to rip up only one branch of a multi-terminal net
14 // FEATURE: re-placement based on routing congestion
15 // note: must assign a cost to "bare wire" -- if not, the
16 // placer will fail to recognize moves that put blocks closer
17 // together, thereby decreasing the potential for future
20 // FEATURE: A* search (chap7 of independence thesis)
22 // FIXME: distinguish out,xo,yo
23 // FIXME: y-axis shortcuts
24 // FEATURE: ability to use a cell for routing purposes
25 // FEATURE: global two-sector-long wires
27 public class MPARDemo {
29 public static final double alphaParameter = 00.9;
30 public static final double betaParameter = 02.5;
31 public static final double gammaParameter = 1.0;
33 public static class FlatNetlist {
35 private HashMap<String,Integer> ids = new HashMap<String,Integer>();
37 public HashSet<Node> nodes = new HashSet<Node>();
38 public HashSet<Net> nets = new HashSet<Net>();
40 /** a node is some primitive element; a potential configuration of a CLB */
42 public PhysicalDevice.PhysicalCell physicalCell = null;
43 private final String type;
49 private HashMap<String,Port> ports = new HashMap<String,Port>();
51 public Node(String type) {
53 this.type = type.toLowerCase();
54 Integer num = ids.get(type);
55 this.id = num == null ? 0 : num.intValue();
56 ids.put(type, this.id+1);
58 public String getType() { return type; }
59 public String toString() {
61 return type + "["+id+"]";
62 return type + "@("+x+","+y+")";
64 public Port getPort(String name, boolean driver) {
65 Port p = ports.get(name);
66 if (p==null) ports.put(name, p = new Port(name, driver));
70 public Fpslic.Cell getPlacement(Fpslic fpslic) { return fpslic.cell(x, y); }
71 public void place(Fpslic fpslic) {
72 Fpslic.Cell cell = fpslic.cell(x,y);
78 if (type.equals("and2")) cell.xlut(LUT_SELF & LUT_OTHER);
79 else if (type.equals("or2")) cell.xlut(LUT_SELF | LUT_OTHER);
80 else if (type.equals("xor2")) cell.xlut(LUT_SELF ^ LUT_OTHER);
81 else if (type.equals("buf")) cell.xlut(LUT_SELF);
82 else if (type.equals("inv")) cell.xlut(~LUT_SELF);
83 else if (type.equals("cell0")) return;
86 private int portIndex = 0;
88 /** a port is an input or output to a Node */
90 private final String name;
91 private final boolean driver;
93 public final int index;
94 public Port(String name, boolean driver) {
97 this.index = driver ? 0 : portIndex++;
99 public String toString() { return Node.this + "." + name; }
100 public Node getNode() { return Node.this; }
101 public void connect(Port p) {
102 if (net != null) { net.add(p);
103 } else if (p.net != null) { p.net.add(this);
109 public void route(Fpslic fpslic, Port[] dests, PhysicalDevice pd, FlatNetlist.Net owner) {
110 PhysicalDevice.PhysicalNet[] destsp = new PhysicalDevice.PhysicalNet[dests.length];
111 for(int i=0; i<dests.length; i++) {
112 Port dest = dests[i];
114 case 0: destsp[i] = dest.getNode().physicalCell.getNet("xi"); break;
115 case 1: destsp[i] = dest.getNode().physicalCell.getNet("yi"); break;
116 default: throw new Error();
119 //System.out.println(physicalCell.getNet("out"));
120 //System.out.println(destsp[0]);
121 pd.route(physicalCell.getNet("out"), destsp, owner);
124 Fpslic.Cell driverCell = fpslic.cell(getNode().x,getNode().y);
125 Fpslic.Cell destCell = fpslic.cell(dest.getNode().x,dest.getNode().y);
126 boolean[] hblocked = new boolean[5];
127 boolean[] vblocked = new boolean[5];
130 int minx = Math.min(getNode().x, dest.getNode().x);
131 int miny = Math.min(getNode().y, dest.getNode().y);
132 int maxx = Math.max(getNode().x, dest.getNode().x);
133 int maxy = Math.max(getNode().y, dest.getNode().y);
134 for(int cx = 0; cx <= 3; cx++) {
135 Fpslic.Cell c = fpslic.cell(cx, getNode().y);
136 for(int i=0; i<5; i++)
137 hblocked[i] |= (c.hx(i) && !c.equals(driverCell));
139 for(int cy = 0; cy <= 3; cy++) {
140 Fpslic.Cell c = fpslic.cell(dest.getNode().x, cy);
141 for(int i=0; i<5; i++)
142 vblocked[i] |= (c.vx(i) && !c.equals(driverCell));
145 for(; free < 5; free++) if (!hblocked[free]) break;
146 for(; free < 5; free++) if (!vblocked[free]) break;
147 if (free >= 5) throw new RuntimeException("unroutable!");
148 Fpslic.Cell turnCell = fpslic.cell(dest.getNode().x, getNode().y);
149 driverCell.out(free, true);
150 driverCell.h(free, true);
151 turnCell.h(free, true);
152 turnCell.v(free, true);
154 case 0: destCell.xi(L0 + free); break;
155 case 1: destCell.yi(L0 + free); break;
156 case 2: destCell.wi(L0 + free); break;
157 case 3: destCell.zi(L0 + free); break;
158 default: throw new RuntimeException("error");
160 destCell.v(free, true);
161 System.out.println("route " + this + " -> " + dest + " on planes " + free);
167 /** a Net is a collection of ports which are wired together */
168 public class Net implements Iterable<Node.Port> {
169 private Node.Port driver = null;
170 private HashSet<Node.Port> ports = new HashSet<Node.Port>();
171 public Net() { nets.add(this); }
172 public Iterator<Node.Port> iterator() { return ports.iterator(); }
173 public int getSize() { return ports.size(); }
174 public HashSet<PhysicalDevice.PhysicalPip> pips = new HashSet<PhysicalDevice.PhysicalPip>();
175 public HashSet<PhysicalDevice.PhysicalNet> pns = new HashSet<PhysicalDevice.PhysicalNet>();
176 public boolean routed = false;
177 public void unroute() {
178 for(PhysicalDevice.PhysicalPip pip : pips)
180 for(PhysicalDevice.PhysicalNet net : pns) {
181 net.owners.remove(this);
188 public void route(Fpslic fpslic, PhysicalDevice pd) {
189 if (driver == null) return;
191 //System.out.println();
192 //System.out.println("routing " + this);
193 Node.Port[] dests = new Node.Port[ports.size() - (ports.contains(driver) ? 1 : 0)];
195 for(Node.Port p : ports)
198 driver.route(fpslic, dests, pd, this);
201 public void add(Node.Port p) {
203 if (driver != null && driver != p)
204 throw new RuntimeException("two drivers on a port!\n "+driver+"\n "+p);
207 if (p.net==this || ports.contains(p)) return;
212 public void add(Net n) {
213 if (n==this || n==null) return;
214 for(Node.Port p : n) add(p);
217 public String toString() {
218 StringBuffer ret = new StringBuffer();
219 ret.append(driver==null ? "()" : driver.toString());
221 for(Node.Port p : this)
224 return ret.toString();
229 public HashMap<EdifCellInstance,FlatNetlist.Node> cache =
230 new HashMap<EdifCellInstance,FlatNetlist.Node>();
231 public HashMap<String,FlatNetlist.Node> top =
232 new HashMap<String,FlatNetlist.Node>();
234 public FlatNetlist.Node createNode(EdifCellInstance eci, String portName) {
235 FlatNetlist.Node n = eci==null ? top.get(portName) : cache.get(eci);
236 if (n != null) return n;
238 n = new FlatNetlist.Node("top_"+portName);
239 top.put(portName, n);
242 n = new FlatNetlist.Node(eci.getType());
245 for(EdifPortRef epr : eci.getAllEPRs()) {
246 EdifPort ep = epr.getPort();
247 EdifNet en = epr.getNet();
248 String name = ep.getOldName();
249 boolean driver = ep.getDirection()==ep.OUT;
250 if (eci==null) driver = !driver;
251 if (eci==null) name = driver ? "out" : "xi";
252 FlatNetlist.Node.Port p = n.getPort(name, driver);
253 for(EdifPortRef epr2 : en.getConnectedPortRefs()) {
254 EdifCellInstance eci2 = epr2.getCellInstance();
255 EdifPort ep2 = epr2.getPort();
256 Node n2 = createNode(eci2, ep2.getOldName());
257 driver = ep2.getDirection()==ep.OUT;
258 name = ep2.getOldName();
259 if (eci2==null) driver = !driver;
260 if (eci2==null) name = driver ? "out" : "xi";
261 FlatNetlist.Node.Port p2 = n2.getPort(name, driver);
270 test code for inter-sector switchboxes
271 public static void main2() throws Exception {
272 Fpslic fpslic = new FtdiBoard();
274 fpslic.cell(23,15).h(3, true);
275 fpslic.cell(23,15).yi(L3);
276 fpslic.cell(23,15).ylut(0xAA);
277 fpslic.iob_right(15, true).enableOutput(WEST);
278 fpslic.cell(23,0).ylut(0x00);
279 fpslic.iob_right(0, true).enableOutput(WEST);
281 for(int x=0; x<20; x++) {
282 for(int y=0; y<20; y++) {
283 for(int l=0; l<5; l++) {
284 for(int v = 0; v <= 1; v++) {
286 int newx = vert ? x : x-1;
287 int newy = vert ? y-1 : y;
288 if (newx<0 || newy<0) continue;
289 if (vert && (y%4) != 0) continue;
290 if (!vert && (x%4) != 0) continue;
293 if (layer==3) continue;
294 Fpslic.Cell c = fpslic.cell(x, y);
295 Fpslic.Cell c2 = fpslic.cell(newx, newy);
296 Fpslic.SectorWire sw1 = vert ? c.vwire(layer) : c.hwire(layer);
297 Fpslic.SectorWire sw2 = vert ? c2.vwire(layer) : c2.hwire(layer);
298 sw1.drives(sw2, true);
301 if (vert) c.v(L0 + layer, true);
302 else c.h(L0 + layer, true);
303 c.out(L0 + layer, true);
307 if (vert) c2.v(L0 + layer, true);
308 else c2.h(L0 + layer, true);
313 System.out.print(x+","+y+","+l+","+(vert?"v":"h")+": ");
316 boolean good = scan(fpslic, c2)==0;
318 System.out.print(good ? "ok " : "bad ");
321 good = scan(fpslic, c2)!=0;
323 System.out.print(good ? "ok " : "bad ");
324 System.out.println();
325 sw1.drives(sw2, false);
326 if (vert) c.v(layer, false);
327 else c.h(layer, false);
333 System.out.println("fails = " + fails);
336 public static int fails = 0;
339 public static void main(String[] s) throws Exception {
340 EdifEnvironment topEnv = new EdifEnvironment("top");
341 EdifLibraryManager elm = new EdifLibraryManager(topEnv);
342 EdifLibrary initLib = new EdifLibrary(elm, "initLib");
343 EdifEnvironment env = EdifMergeParser.parseAndMerge(s, initLib);
344 System.out.println("top is " + env.getTopCell());
345 FlatNetlist fnl = new FlatNetlist();
347 for(Iterator<EdifCellInstance> it = (Iterator<EdifCellInstance>)env.getTopCell().cellInstanceIterator();
350 FlatNetlist.Node n = fnl.createNode(it.next(), null);
353 Fpslic fpslic = new FtdiBoard();
354 PhysicalDevice pd = new PhysicalDevice(fpslic, 20, 20);
360 Random rand = new Random();
361 boolean[][] used = new boolean[pd.width][pd.height];
362 for(FlatNetlist.Node n : fnl.nodes) {
364 px = Math.abs(rand.nextInt()) % pd.width;
365 py = Math.abs(rand.nextInt()) % pd.height;
370 n.physicalCell = pd.getCell(px, py);
371 System.out.println("placed " + n + " at ("+px+","+py+")");
379 HashSet<FlatNetlist.Net> needUnroute = new HashSet<FlatNetlist.Net>();
381 System.out.println();
382 System.out.println("routing trial " + (++trial));
383 for(FlatNetlist.Net net : fnl.nets) {
384 if (net.getSize() <= 1) continue;
385 net.route(fpslic, pd);
387 double congestion = 0;
390 for(PhysicalDevice.PhysicalNet pn : pd.allPhysicalNets) {
392 //System.out.println("overrouted: " + pn + ", congestion="+pn.congestion + ", load=" + pn.load);
394 congestion += pn.congestion;
396 pn.congestion = pn.congestion * alphaParameter;
398 pn.congestion += betaParameter;
399 // don't do this here
400 //pn.congestion += betaParameter;
401 for(FlatNetlist.Net n : pn.owners)
405 System.out.println(" overrouted="+overrouted+", congestion="+congestion +", ripping up " + needUnroute.size() +" nets of " + fnl.nets.size());
406 if (overrouted <= 0) break;
407 //for(FlatNetlist.Net net : fnl.nets)
408 for(FlatNetlist.Net net : needUnroute)
411 for(PhysicalDevice.PhysicalNet pn : pd.allPhysicalNets)
412 for(PhysicalDevice.PhysicalPip pip : pn) {
419 fpslic.cell(23,15).h(3, true);
420 fpslic.cell(23,15).yi(L3);
421 fpslic.cell(23,15).ylut(0xAA);
422 fpslic.iob_right(15, true).enableOutput(WEST);
423 fpslic.cell(23,0).ylut(0x00);
424 fpslic.iob_right(0, true).enableOutput(WEST);
429 int a = Math.abs(rand.nextInt()) % (1 << width);
430 int b = Math.abs(rand.nextInt()) % (1 << width);
431 setInput(fnl, fpslic, "a", a);
432 setInput(fnl, fpslic, "b", b);
433 setInput(fnl, fpslic, "ci", 0);
434 int result = getOutput(fnl, fpslic, "out");
435 System.out.println(Integer.toString(a,16) + " + " +
436 Integer.toString(b,16) + " = " +
437 Integer.toString(result,16) +
438 " [ " + (a+b==result ? "ok" : "bad" ) + " ] ");
442 public static class PhysicalDevice {
443 private final Fpslic fpslic;
445 public final int width;
446 public final int height;
447 private final PhysicalNet[][][][] sectorWires;
448 private final PhysicalCell[][] cells;
450 public PhysicalCell getCell(int col, int row) {
451 if (col<0) return null;
452 if (row<0) return null;
453 if (col>=width) return null;
454 if (row>=height) return null;
455 return cells[col][row];
458 public PhysicalDevice(final Fpslic fpslic, int width, int height) {
459 this.fpslic = fpslic;
461 this.height = height;
462 sectorWires = new PhysicalNet[width][height][5][2];
463 for(int x=0; x<width; x+=4)
464 for(int y=0; y<height; y+=4)
465 for(int p=0; p<5; p++) {
466 for(int xc=x; xc<x+4; xc++) {
467 PhysicalNet vwire = new PhysicalNet("("+xc+","+y+"-"+(y+3)+")");
468 for(int yc=y; yc<y+4; yc++)
469 sectorWires[xc][yc][p][0] = vwire;
471 for(int yc=y; yc<y+4; yc++) {
472 PhysicalNet hwire = new PhysicalNet("("+x+"-"+(x+3)+","+yc+")");
473 for(int xc=x; xc<x+4; xc++)
474 sectorWires[xc][yc][p][1] = hwire;
478 for(int x=4; x<width; x+=4) {
479 for(int y=0; y<height; y++) {
480 for(int p=0; p<5; p++) {
484 new PhysicalPip("xxx",
485 sectorWires[x-1][y][p][1],
486 new PhysicalNet[] { sectorWires[x][y][p][1] },
488 public void set(boolean connected) {
489 fpslic.cell(xc-1, yc).hwire(pc).drives(fpslic.cell(xc, yc).hwire(pc), connected);
492 new PhysicalPip("xxx",
493 sectorWires[x][y][p][1],
494 new PhysicalNet[] { sectorWires[x-1][y][p][1] },
496 public void set(boolean connected) {
497 fpslic.cell(xc, yc).hwire(pc).drives(fpslic.cell(xc-1, yc).hwire(pc), connected);
504 for(int x=0; x<width; x++) {
505 for(int y=4; y<height; y+=4) {
506 for(int p=0; p<5; p++) {
510 new PhysicalPip("xxx",
511 sectorWires[x][y-1][p][0],
512 new PhysicalNet[] { sectorWires[x][y][p][0] },
514 public void set(boolean connected) {
515 fpslic.cell(xc, yc-1).vwire(pc).drives(fpslic.cell(xc, yc).vwire(pc), connected);
518 new PhysicalPip("xxx",
519 sectorWires[x][y][p][0],
520 new PhysicalNet[] { sectorWires[x][y-1][p][0] },
522 public void set(boolean connected) {
523 fpslic.cell(xc, yc).vwire(pc).drives(fpslic.cell(xc, yc-1).vwire(pc), connected);
530 cells = new PhysicalCell[width][height];
531 for(int x=0; x<width; x++)
532 for(int y=0; y<height; y++) {
533 cells[x][y] = new PhysicalCell(x, y);
535 for(int x=0; x<width; x++)
536 for(int y=0; y<height; y++)
540 private PhysicalNet getSectorWire(int col, int row, int plane, boolean horizontal) {
541 return sectorWires[col][row][plane][horizontal ? 1 : 0];
544 public class PhysicalCell {
546 public PhysicalNet getNet(String name) {
547 if (name.equals("out")) return outputNet;
548 if (name.equals("xi")) return xin;
549 if (name.equals("yi")) return yin;
550 throw new RuntimeException("unknown");
555 private PhysicalNet outputNet;
556 private PhysicalNet xin;
557 private PhysicalNet yin;
558 private PhysicalNet[] local = new PhysicalNet[5];
560 private Fpslic.Cell cell() { return fpslic.cell(col, row); }
562 public void setFunction(String type) {
563 Fpslic.Cell cell = cell();
568 if (type.equals("and2")) cell.xlut(LUT_SELF & LUT_OTHER);
569 else if (type.equals("or2")) cell.xlut(LUT_SELF | LUT_OTHER);
570 else if (type.equals("xor2")) cell.xlut(LUT_SELF ^ LUT_OTHER);
571 else if (type.equals("buf")) cell.xlut(LUT_SELF);
572 else if (type.equals("inv")) cell.xlut(~LUT_SELF);
576 // FIXME wow, this is a horrendous hack!
577 if (getCell(col-1, row+1) != null)
578 new PhysicalPip(this+".xiNW", getCell(col-1, row+1).getNet("out"), new PhysicalNet[] { xin }, 5) {
579 public void set(boolean connected) { cell().xi(connected ? NW : NONE); }
581 if (getCell(col-1, row-1) != null)
582 new PhysicalPip(this+".xiSW", getCell(col-1, row-1).getNet("out"), new PhysicalNet[] { xin }, 5) {
583 public void set(boolean connected) { cell().xi(connected ? SW : NONE); }
585 if (getCell(col+1, row+1) != null)
586 new PhysicalPip(this+".xiNE", getCell(col+1, row+1).getNet("out"), new PhysicalNet[] { xin }, 5) {
587 public void set(boolean connected) { cell().xi(connected ? NE : NONE); }
589 if (getCell(col+1, row-1) != null)
590 new PhysicalPip(this+".xiSE", getCell(col+1, row-1).getNet("out"), new PhysicalNet[] { xin }, 5) {
591 public void set(boolean connected) { cell().xi(connected ? SE : NONE); }
595 private PhysicalCell(int col, int row) {
598 outputNet = new PhysicalNet(this.toString()+".out");
599 xin = new PhysicalNet(this.toString()+".xi");
600 yin = new PhysicalNet(this.toString()+".yi");
601 for(int j=0; j<5; j++) {
603 // plane 3 is reserved for debugging
607 local[i] = new PhysicalNet(this.toString()+".L"+i);
608 new PhysicalPip(this+".h"+i, null, new PhysicalNet[] { local[i], getSectorWire(col, row, i, true) }) {
609 public void set(boolean connected) { cell().h(i, connected); }
611 new PhysicalPip(this+".v"+i, null, new PhysicalNet[] { local[i], getSectorWire(col, row, i, false) }) {
612 public void set(boolean connected) { cell().v(i, connected); }
614 new PhysicalPip(this+".xi"+i, local[i], new PhysicalNet[] { xin }) {
615 public void set(boolean connected) { cell().xi(connected ? i : NONE); }
617 new PhysicalPip(this+".yi"+i, local[i], new PhysicalNet[] { yin }) {
618 public void set(boolean connected) { cell().yi(connected ? i : NONE); }
620 new PhysicalPip(this+".o"+i, outputNet, new PhysicalNet[] { local[i] }) {
621 public void set(boolean connected) { cell().out(i, connected); }
625 public String toString() { return "cell@("+col+","+row+")"; }
629 public void route(PhysicalNet source, PhysicalNet[] dests, FlatNetlist.Net owner) {
630 HashSet<PhysicalNet> remainingDests = new HashSet<PhysicalNet>();
631 for(PhysicalNet dest : dests) remainingDests.add(dest);
633 HashSet<PhysicalNet> needsReset = new HashSet<PhysicalNet>();
634 PriorityQueue<PhysicalNet> pq = new PriorityQueue<PhysicalNet>();
635 needsReset.add(source);
640 PhysicalNet pn = pq.poll();
641 if (pn==null) throw new Error("unroutable! " + source + " -> " + dests[0]);
642 double frontier = pn.distance;
643 for(PhysicalPip pip : pn)
644 for(PhysicalNet net : pip.getDrivenNets()) {
645 double newfrontier = frontier + 0.05 + net.congestion;
647 // penalty for using any net already routed in this iteration (makes routing order-sensitive)
648 if (net.load >= 1) newfrontier = newfrontier + 20;
650 if (net.distance <= newfrontier) continue;
651 pq.remove(net); // if already in there
652 net.distance = newfrontier;
655 net.backpointer = pn;
656 if (remainingDests.contains(net)) {
657 remainingDests.remove(net);
658 if (remainingDests.size()==0) break OUTER;
660 // Vaughn Betz style multiterminal routing: once we reach one sink, make every node on the path
661 // "distance zero" from the source.
662 for(PhysicalNet pnx = net; pnx != null; pnx = pnx.backpointer) {
671 for(PhysicalNet dest : dests) {
672 PhysicalNet pn = dest;
673 while(pn != null && pn.backpointer != null) {
674 pn.owners.add(owner);
676 if (pn.distance != Double.MAX_VALUE) {
677 pn.distance = Double.MAX_VALUE;
679 if (pn.load>=2) pn.congestion += betaParameter;
681 PhysicalPip pip = pn.getPipFrom(pn.backpointer);
686 // FIXME: check pn==source at this point
689 for(PhysicalNet pn : needsReset) {
690 pn.distance = Double.MAX_VALUE;
691 pn.backpointer = null;
694 public HashSet<PhysicalNet> allPhysicalNets = new HashSet<PhysicalNet>();
695 public class PhysicalNet implements Iterable<PhysicalPip>, Comparable<PhysicalNet> {
696 public double congestion = 0;
698 public double distance = Double.MAX_VALUE;
699 public PhysicalNet backpointer = null;
701 public int compareTo(PhysicalNet pn) {
702 double x = distance - pn.distance;
703 return distance > pn.distance
705 : distance < pn.distance
710 private final HashSet<PhysicalPip> pips = new HashSet<PhysicalPip>();
711 public Iterator<PhysicalPip> iterator() { return pips.iterator(); }
713 public PhysicalNet(String name) {
715 allPhysicalNets.add(this);
717 public String toString() { return name; }
718 private void addPip(PhysicalPip pip) { pips.add(pip); }
719 public PhysicalPip getPipFrom(PhysicalNet pn) {
720 for(PhysicalPip pip : pn)
721 for(PhysicalNet pn2 : pip.getDrivenNets())
726 public HashSet<FlatNetlist.Net> owners = new HashSet<FlatNetlist.Net>();
729 public abstract class PhysicalPip {
730 private PhysicalNet driver;
731 private PhysicalNet[] driven;
733 private int defaultCost;
734 public String toString() { return name; }
735 public PhysicalNet getDriverNet() { return driver; }
736 public PhysicalNet[] getDrivenNets() { return driven; }
737 public int getCost(PhysicalNet in, PhysicalNet out) { return defaultCost; }
738 public PhysicalPip(String name, PhysicalNet driver, PhysicalNet[] driven) { this(name, driver, driven, 100); }
739 public PhysicalPip(String name, PhysicalNet driver, PhysicalNet[] driven, int defaultCost) {
741 this.driver = driver;
742 this.driven = driven;
743 this.defaultCost = defaultCost;
744 if (driver != null) driver.addPip(this);
745 for(PhysicalNet pn : driven) pn.addPip(this);
747 public abstract void set(boolean connected);
752 private static int ret;
753 public static synchronized int scan(final Fpslic device, final Fpslic.Cell cell) {
755 scan(device, cell, YLUT, true);
756 ((FtdiBoard)device).readBus(new FtdiBoard.ByteCallback() {
757 public void call(byte b) throws Exception {
759 synchronized(device) {
764 synchronized(device) {
767 } catch (Exception e) { throw new RuntimeException(e); }
769 scan(device, cell, YLUT, false);
771 } catch (Exception e) { throw new RuntimeException(e); }
774 public static void scan(Fpslic dev, Fpslic.Cell cell, int source, boolean setup) {
776 //if (source != NONE) cell.c(source);
777 if (cell.b()) cell.b(false);
778 if (cell.f()) cell.f(false);
780 if (cell.out(L3)!=setup) cell.out(L3, setup);
781 if (cell.vx(L3)!=setup) cell.v(L3, setup);
783 Fpslic.SectorWire sw = cell.vwire(L3);
784 //System.out.println("wire is: " + sw);
786 if (sw.row > (12 & ~0x3) && sw.north()!=null && sw.north().drives(sw))
787 sw.north().drives(sw, false);
788 while(sw.row > (12 & ~0x3) && sw.south() != null) {
789 //System.out.println(sw + " -> " + sw.south());
790 if (sw.drives(sw.south())!=setup) sw.drives(sw.south(), setup);
793 if (sw.row < (12 & ~0x3) && sw.south() != null && sw.south().drives(sw))
794 sw.north().drives(sw, false);
795 while(sw.row < (12 & ~0x3) && sw.north() != null) {
796 //System.out.println(sw + " -> " + sw.north());
797 if (sw.drives(sw.north())!=setup) sw.drives(sw.north(), setup);
801 //cell = dev.cell(19, 15);
802 cell = dev.cell(cell.col, 15);
804 System.out.println("cell is " + cell);
813 if (cell.hx(L3) != setup) cell.h(L3, setup);
814 if (cell.vx(L3) != setup) cell.v(L3, setup);
817 if (sw.west()!=null && sw.west().drives(sw)) { sw.west().drives(sw, false); }
818 while(sw.east() != null) {
819 //System.out.println(sw + " -> " + sw.east());
820 if (sw.drives(sw.east())!=setup) sw.drives(sw.east(), setup);
826 public static void setInput(FlatNetlist fnl, Fpslic fpslic, String prefix, int val) {
827 for(int i=0; ; i++) {
828 FlatNetlist.Node n = fnl.top.get(prefix + "["+i+"]");
829 if (n==null && i==0) n = fnl.top.get(prefix);
831 Fpslic.Cell c = n.getPlacement(fpslic);
834 c.xlut((val & 0x1)==0 ? 0x00 : 0xff);
838 public static int getOutput(FlatNetlist fnl, Fpslic fpslic, String prefix) {
840 for(int i=0; ; i++) {
841 FlatNetlist.Node n = fnl.top.get(prefix+"["+i+"]");
842 if (n==null && i==0) n = fnl.top.get(prefix);
843 if (n==null) return val;
844 Fpslic.Cell c = n.getPlacement(fpslic);
849 int scan = scan(fpslic, c);
850 val |= ((scan==0 ? 0 : 1) << i);