updates that were lying around but never got checked in; includes reorg of gui
[slipway.git] / src / edu / berkeley / slipway / mpar / NetList.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 java.awt.*;
8 import edu.berkeley.slipway.*;
9 import com.atmel.fpslic.*;
10 import static com.atmel.fpslic.FpslicConstants.*;
11 import static edu.berkeley.slipway.mpar.MPARDemo.*;
12
13 public class NetList implements Iterable<NetList.Node> {
14
15     public NetList(String s) throws EdifNameConflictException, InvalidEdifNameException {
16         EdifEnvironment topEnv = new EdifEnvironment("top");
17         EdifLibraryManager elm = new EdifLibraryManager(topEnv);
18         EdifLibrary initLib = new EdifLibrary(elm, "initLib");
19         EdifEnvironment env = EdifMergeParser.parseAndMerge(new String[] { s }, initLib);
20         for(Iterator<EdifCellInstance> it = (Iterator<EdifCellInstance>)env.getTopCell().cellInstanceIterator();
21             it.hasNext();
22             ) {
23             createNode(it.next(), null);
24         }
25     }
26
27     private HashMap<String,Integer> ids = new HashMap<String,Integer>();
28
29     public HashSet<Node>        nodes  = new HashSet<Node>();
30     public ArrayList<Node>      nodes_ = new ArrayList<Node>();
31
32     public HashSet<LogicalNet>  nets  = new HashSet<LogicalNet>();
33     public Iterable<NetList.LogicalNet> getLogicalNets() { return nets; }
34
35     /** a node is some primitive element; a potential configuration of a CLB */
36     public class Node implements Iterable<Node.Port> {
37         private final String type;
38         private final int    id;
39
40         private HashMap<String,Port> ports = new HashMap<String,Port>();
41         public Iterator<Port> iterator() { return ports.values().iterator(); }
42
43         public Node(String type) {
44             nodes.add(this);
45             nodes_.add(this);
46             this.type = type.toLowerCase();
47             Integer num = ids.get(type);
48             this.id = num == null ? 0 : num.intValue();
49             ids.put(type, this.id+1);
50         }
51         public String getType() { return type; }
52         public String toString() {
53             return type;
54         }
55         public Port getPort(String name, boolean driver) {
56             Port p = ports.get(name);
57             if (p==null) ports.put(name, p = new Port(name, driver));
58             return p;
59         }
60
61         private int portIndex = 0;
62         /** a port is an input or output to a Node */
63         public class Port {
64             private final String name;
65             private final boolean driver;
66             LogicalNet    net;
67             public final int index;
68             public Port(String name, boolean driver) {
69                 this.name = name;
70                 this.driver = driver;
71                 this.index = driver ? 0 : portIndex++;
72             }
73             public String toString() { return Node.this + "." + name; }
74             public Node getNode() { return Node.this; }
75             public void connect(Port p) {
76                 if (net != null)          { net.add(p);
77                 } else if (p.net != null) { p.net.add(this);
78                 } else {
79                     new LogicalNet().add(this);
80                     this.net.add(p);
81                 }
82             }
83         }
84     }
85
86     /** a Net is a collection of ports which are wired together */
87     public class LogicalNet implements Iterable<Node.Port> {
88          Node.Port driver = null;
89          HashSet<Node.Port> ports = new HashSet<Node.Port>();
90
91         public LogicalNet() { nets.add(this); }
92         public Iterator<Node.Port> iterator() { return ports.iterator(); }
93         public int getSize() { return ports.size(); }
94
95         public void add(Node.Port p) {
96             if (p.driver) {
97                 if (driver != null && driver != p)
98                     throw new RuntimeException("two drivers on a port!\n  "+driver+"\n  "+p);
99                 driver = p;
100             }
101             if (p.net==this || ports.contains(p)) return;
102             ports.add(p);
103             add(p.net);
104             p.net = this;
105         }
106         public void add(LogicalNet n) {
107             if (n==this || n==null) return;
108             for(Node.Port p : n) add(p);
109             nets.remove(n);
110         }
111         public String toString() {
112             StringBuffer ret = new StringBuffer();
113             ret.append(driver==null ? "()" : driver.toString());
114             ret.append(" -> ");
115             for(Node.Port p : this)
116                 if (p!=driver)
117                     ret.append(p+" ");
118             return ret.toString();
119         }
120     }
121
122
123     public HashMap<EdifCellInstance,NetList.Node> cache =
124         new HashMap<EdifCellInstance,NetList.Node>();
125     public HashMap<String,NetList.Node> top =
126         new HashMap<String,NetList.Node>();
127        
128     public NetList.Node createNode(EdifCellInstance eci, String portName) {
129         NetList.Node n = eci==null ? top.get(portName) : cache.get(eci);
130         if (n != null) return n;
131         if (eci==null) {
132             n = new NetList.Node("top_"+portName);
133             top.put(portName, n);
134             return n;
135         } else {
136             n = new NetList.Node(eci.getType());
137             cache.put(eci,n);
138         }
139         for(EdifPortRef epr : eci.getAllEPRs()) {
140             EdifPort ep = epr.getPort();
141             EdifNet  en = epr.getNet();
142             String name = ep.getOldName();
143             boolean driver = ep.getDirection()==ep.OUT;
144             if (eci==null) driver = !driver;
145             if (eci==null) name = driver ? "out" : "xi";
146             NetList.Node.Port p = n.getPort(name, driver);
147             for(EdifPortRef epr2 : en.getConnectedPortRefs()) {
148                 EdifCellInstance eci2 = epr2.getCellInstance();
149                 EdifPort ep2 = epr2.getPort();
150                 Node n2 = createNode(eci2, ep2.getOldName());
151                 driver = ep2.getDirection()==ep.OUT;
152                 name = ep2.getOldName();
153                 if (eci2==null) driver = !driver;
154                 if (eci2==null) name = driver ? "out" : "xi";
155                 NetList.Node.Port p2 = n2.getPort(name, driver);
156                 p.connect(p2);
157             }
158         }
159         return n;
160     }
161
162     public Node randomNode(Random rand) {
163         return nodes_.get(Math.abs(rand.nextInt()) % nodes_.size());
164     }
165
166     public Iterator<Node> iterator() { return nodes.iterator(); }
167 }