1 package edu.berkeley.slipway.mpar;
2 import com.atmel.fpslic.*;
3 import byucc.edif.tools.merge.*;
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.*;
13 public class NetList implements Iterable<NetList.Node> {
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();
23 createNode(it.next(), null);
27 private HashMap<String,Integer> ids = new HashMap<String,Integer>();
29 public HashSet<Node> nodes = new HashSet<Node>();
30 public ArrayList<Node> nodes_ = new ArrayList<Node>();
32 public HashSet<LogicalNet> nets = new HashSet<LogicalNet>();
33 public Iterable<NetList.LogicalNet> getLogicalNets() { return nets; }
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;
40 private HashMap<String,Port> ports = new HashMap<String,Port>();
41 public Iterator<Port> iterator() { return ports.values().iterator(); }
43 public Node(String type) {
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);
51 public String getType() { return type; }
52 public String toString() {
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));
61 private int portIndex = 0;
62 /** a port is an input or output to a Node */
64 private final String name;
65 private final boolean driver;
67 public final int index;
68 public Port(String name, boolean driver) {
71 this.index = driver ? 0 : portIndex++;
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);
79 new LogicalNet().add(this);
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>();
91 public LogicalNet() { nets.add(this); }
92 public Iterator<Node.Port> iterator() { return ports.iterator(); }
93 public int getSize() { return ports.size(); }
95 public void add(Node.Port p) {
97 if (driver != null && driver != p)
98 throw new RuntimeException("two drivers on a port!\n "+driver+"\n "+p);
101 if (p.net==this || ports.contains(p)) return;
106 public void add(LogicalNet n) {
107 if (n==this || n==null) return;
108 for(Node.Port p : n) add(p);
111 public String toString() {
112 StringBuffer ret = new StringBuffer();
113 ret.append(driver==null ? "()" : driver.toString());
115 for(Node.Port p : this)
118 return ret.toString();
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>();
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;
132 n = new NetList.Node("top_"+portName);
133 top.put(portName, n);
136 n = new NetList.Node(eci.getType());
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);
162 public Node randomNode(Random rand) {
163 return nodes_.get(Math.abs(rand.nextInt()) % nodes_.size());
166 public Iterator<Node> iterator() { return nodes.iterator(); }