reorganize mpar code
[slipway.git] / src / edu / berkeley / slipway / mpar / FlatNetlist.java
1 package edu.berkeley.slipway.mpar;
2 import com.atmel.fpslic.*;
3 import byucc.edif.tools.merge.*;
4 import byucc.edif.*;
5 import java.io.*;
6 import java.util.*;
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.*;
11
12 public class FlatNetlist {
13
14     private HashMap<String,Integer> ids = new HashMap<String,Integer>();
15
16     public HashSet<Node> nodes = new HashSet<Node>();
17     public HashSet<Net>  nets  = new HashSet<Net>();
18
19     /** a node is some primitive element; a potential configuration of a CLB */
20     public class Node {
21         public PhysicalDevice.PhysicalCell physicalCell = null;
22         private final String type;
23         private final int    id;
24
25         public int x = -1;
26         public int y = -1;
27
28         private HashMap<String,Port> ports = new HashMap<String,Port>();
29
30         public Node(String type) {
31             nodes.add(this);
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);
36         }
37         public String getType() { return type; }
38         public String toString() {
39             if (x==-1 || y==-1)
40                 return type + "["+id+"]";
41             return type + "@("+x+","+y+")";
42         }
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));
46             return p;
47         }
48
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);
52             cell.c(XLUT);
53             cell.b(false);
54             cell.f(false);
55             cell.xi(NW);
56             cell.yi(EAST);
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;
63         }
64
65         private int portIndex = 0;
66
67         /** a port is an input or output to a Node */
68         public class Port {
69             private final String name;
70             private final boolean driver;
71             Net    net;
72             public final int index;
73             public Port(String name, boolean driver) {
74                 this.name = name;
75                 this.driver = driver;
76                 this.index = driver ? 0 : portIndex++;
77             }
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);
83                 } else {
84                     new Net().add(this);
85                     this.net.add(p);
86                 }
87             }
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++) {
91                     Port dest = dests[i];
92                     switch(dest.index) {
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();
96                     }
97                 }
98                 //System.out.println(physicalCell.getNet("out"));
99                 //System.out.println(destsp[0]);
100                 pd.route(physicalCell.getNet("out"), destsp, owner);
101
102                 /*
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];
107                   hblocked[3] = true;
108                   vblocked[3] = true;
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));
117                   }
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));
122                   }
123                   int free = 0;
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);
132                   switch(dest.index) {
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");
138                   }
139                   destCell.v(free, true);
140                   System.out.println("route " + this + " -> " + dest + " on planes " + free);
141                 */
142             }
143         }
144     }
145
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)
158                 pip.set(false);
159             for(PhysicalDevice.PhysicalNet net : pns) {
160                 net.owners.remove(this);
161                 net.load--;
162             }
163             pips.clear();
164             pns.clear();
165             routed = false;
166         }
167         public void route(Fpslic fpslic, PhysicalDevice pd) {
168             if (driver == null) return;
169             if (routed) 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)];
173             int i = 0;
174             for(Node.Port p : ports)
175                 if (p != driver)
176                     dests[i++] = p;
177             driver.route(fpslic, dests, pd, this);
178             routed = true;
179         }
180         public void add(Node.Port p) {
181             if (p.driver) {
182                 if (driver != null && driver != p)
183                     throw new RuntimeException("two drivers on a port!\n  "+driver+"\n  "+p);
184                 driver = p;
185             }
186             if (p.net==this || ports.contains(p)) return;
187             ports.add(p);
188             add(p.net);
189             p.net = this;
190         }
191         public void add(Net n) {
192             if (n==this || n==null) return;
193             for(Node.Port p : n) add(p);
194             nets.remove(n);
195         }
196         public String toString() {
197             StringBuffer ret = new StringBuffer();
198             ret.append(driver==null ? "()" : driver.toString());
199             ret.append(" -> ");
200             for(Node.Port p : this)
201                 if (p!=driver)
202                     ret.append(p+" ");
203             return ret.toString();
204         }
205     }
206
207
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>();
212        
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;
216         if (eci==null) {
217             n = new FlatNetlist.Node("top_"+portName);
218             top.put(portName, n);
219             return n;
220         } else {
221             n = new FlatNetlist.Node(eci.getType());
222             cache.put(eci,n);
223         }
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);
241                 p.connect(p2);
242             }
243         }
244         return n;
245     }
246 }