1 package edu.berkeley.slipway.mpar;
2 import com.atmel.fpslic.*;
3 import byucc.edif.tools.merge.*;
7 import edu.berkeley.slipway.*;
8 import com.atmel.fpslic.*;
9 import static com.atmel.fpslic.FpslicConstants.*;
10 import static edu.berkeley.slipway.mpar.MPARDemo.*;
12 public class FlatNetlist {
14 private HashMap<String,Integer> ids = new HashMap<String,Integer>();
16 public HashSet<Node> nodes = new HashSet<Node>();
17 public HashSet<Net> nets = new HashSet<Net>();
19 /** a node is some primitive element; a potential configuration of a CLB */
21 public PhysicalDevice.PhysicalCell physicalCell = null;
22 private final String type;
28 private HashMap<String,Port> ports = new HashMap<String,Port>();
30 public Node(String type) {
32 this.type = type.toLowerCase();
33 Integer num = ids.get(type);
34 this.id = num == null ? 0 : num.intValue();
35 ids.put(type, this.id+1);
37 public String getType() { return type; }
38 public String toString() {
40 return type + "["+id+"]";
41 return type + "@("+x+","+y+")";
43 public Port getPort(String name, boolean driver) {
44 Port p = ports.get(name);
45 if (p==null) ports.put(name, p = new Port(name, driver));
49 public Fpslic.Cell getPlacement(Fpslic fpslic) { return fpslic.cell(x, y); }
50 public void place(Fpslic fpslic) {
51 Fpslic.Cell cell = fpslic.cell(x,y);
57 if (type.equals("and2")) cell.xlut(LUT_SELF & LUT_OTHER);
58 else if (type.equals("or2")) cell.xlut(LUT_SELF | LUT_OTHER);
59 else if (type.equals("xor2")) cell.xlut(LUT_SELF ^ LUT_OTHER);
60 else if (type.equals("buf")) cell.xlut(LUT_SELF);
61 else if (type.equals("inv")) cell.xlut(~LUT_SELF);
62 else if (type.equals("cell0")) return;
65 private int portIndex = 0;
67 /** a port is an input or output to a Node */
69 private final String name;
70 private final boolean driver;
72 public final int index;
73 public Port(String name, boolean driver) {
76 this.index = driver ? 0 : portIndex++;
78 public String toString() { return Node.this + "." + name; }
79 public Node getNode() { return Node.this; }
80 public void connect(Port p) {
81 if (net != null) { net.add(p);
82 } else if (p.net != null) { p.net.add(this);
88 public void route(Fpslic fpslic, Port[] dests, PhysicalDevice pd, FlatNetlist.Net owner) {
89 PhysicalDevice.PhysicalNet[] destsp = new PhysicalDevice.PhysicalNet[dests.length];
90 for(int i=0; i<dests.length; i++) {
93 case 0: destsp[i] = dest.getNode().physicalCell.getNet("xi"); break;
94 case 1: destsp[i] = dest.getNode().physicalCell.getNet("yi"); break;
95 default: throw new Error();
98 //System.out.println(physicalCell.getNet("out"));
99 //System.out.println(destsp[0]);
100 pd.route(physicalCell.getNet("out"), destsp, owner);
103 Fpslic.Cell driverCell = fpslic.cell(getNode().x,getNode().y);
104 Fpslic.Cell destCell = fpslic.cell(dest.getNode().x,dest.getNode().y);
105 boolean[] hblocked = new boolean[5];
106 boolean[] vblocked = new boolean[5];
109 int minx = Math.min(getNode().x, dest.getNode().x);
110 int miny = Math.min(getNode().y, dest.getNode().y);
111 int maxx = Math.max(getNode().x, dest.getNode().x);
112 int maxy = Math.max(getNode().y, dest.getNode().y);
113 for(int cx = 0; cx <= 3; cx++) {
114 Fpslic.Cell c = fpslic.cell(cx, getNode().y);
115 for(int i=0; i<5; i++)
116 hblocked[i] |= (c.hx(i) && !c.equals(driverCell));
118 for(int cy = 0; cy <= 3; cy++) {
119 Fpslic.Cell c = fpslic.cell(dest.getNode().x, cy);
120 for(int i=0; i<5; i++)
121 vblocked[i] |= (c.vx(i) && !c.equals(driverCell));
124 for(; free < 5; free++) if (!hblocked[free]) break;
125 for(; free < 5; free++) if (!vblocked[free]) break;
126 if (free >= 5) throw new RuntimeException("unroutable!");
127 Fpslic.Cell turnCell = fpslic.cell(dest.getNode().x, getNode().y);
128 driverCell.out(free, true);
129 driverCell.h(free, true);
130 turnCell.h(free, true);
131 turnCell.v(free, true);
133 case 0: destCell.xi(L0 + free); break;
134 case 1: destCell.yi(L0 + free); break;
135 case 2: destCell.wi(L0 + free); break;
136 case 3: destCell.zi(L0 + free); break;
137 default: throw new RuntimeException("error");
139 destCell.v(free, true);
140 System.out.println("route " + this + " -> " + dest + " on planes " + free);
146 /** a Net is a collection of ports which are wired together */
147 public class Net implements Iterable<Node.Port> {
148 private Node.Port driver = null;
149 private HashSet<Node.Port> ports = new HashSet<Node.Port>();
150 public Net() { nets.add(this); }
151 public Iterator<Node.Port> iterator() { return ports.iterator(); }
152 public int getSize() { return ports.size(); }
153 public HashSet<PhysicalDevice.PhysicalPip> pips = new HashSet<PhysicalDevice.PhysicalPip>();
154 public HashSet<PhysicalDevice.PhysicalNet> pns = new HashSet<PhysicalDevice.PhysicalNet>();
155 public boolean routed = false;
156 public void unroute() {
157 for(PhysicalDevice.PhysicalPip pip : pips)
159 for(PhysicalDevice.PhysicalNet net : pns) {
160 net.owners.remove(this);
167 public void route(Fpslic fpslic, PhysicalDevice pd) {
168 if (driver == null) return;
170 //System.out.println();
171 //System.out.println("routing " + this);
172 Node.Port[] dests = new Node.Port[ports.size() - (ports.contains(driver) ? 1 : 0)];
174 for(Node.Port p : ports)
177 driver.route(fpslic, dests, pd, this);
180 public void add(Node.Port p) {
182 if (driver != null && driver != p)
183 throw new RuntimeException("two drivers on a port!\n "+driver+"\n "+p);
186 if (p.net==this || ports.contains(p)) return;
191 public void add(Net n) {
192 if (n==this || n==null) return;
193 for(Node.Port p : n) add(p);
196 public String toString() {
197 StringBuffer ret = new StringBuffer();
198 ret.append(driver==null ? "()" : driver.toString());
200 for(Node.Port p : this)
203 return ret.toString();
208 public HashMap<EdifCellInstance,FlatNetlist.Node> cache =
209 new HashMap<EdifCellInstance,FlatNetlist.Node>();
210 public HashMap<String,FlatNetlist.Node> top =
211 new HashMap<String,FlatNetlist.Node>();
213 public FlatNetlist.Node createNode(EdifCellInstance eci, String portName) {
214 FlatNetlist.Node n = eci==null ? top.get(portName) : cache.get(eci);
215 if (n != null) return n;
217 n = new FlatNetlist.Node("top_"+portName);
218 top.put(portName, n);
221 n = new FlatNetlist.Node(eci.getType());
224 for(EdifPortRef epr : eci.getAllEPRs()) {
225 EdifPort ep = epr.getPort();
226 EdifNet en = epr.getNet();
227 String name = ep.getOldName();
228 boolean driver = ep.getDirection()==ep.OUT;
229 if (eci==null) driver = !driver;
230 if (eci==null) name = driver ? "out" : "xi";
231 FlatNetlist.Node.Port p = n.getPort(name, driver);
232 for(EdifPortRef epr2 : en.getConnectedPortRefs()) {
233 EdifCellInstance eci2 = epr2.getCellInstance();
234 EdifPort ep2 = epr2.getPort();
235 Node n2 = createNode(eci2, ep2.getOldName());
236 driver = ep2.getDirection()==ep.OUT;
237 name = ep2.getOldName();
238 if (eci2==null) driver = !driver;
239 if (eci2==null) name = driver ? "out" : "xi";
240 FlatNetlist.Node.Port p2 = n2.getPort(name, driver);