+
+ public void dumpFabric(boolean quiet) {
+ // FIXME: this is really ugly: the order of port declarations in
+ // the XXXShip.java file must match the order in the .balsa file!
+
+ ArrayList instructionports = new ArrayList<Port>();
+ for(Ship ship : shiplist)
+ for(Port port : ship.portlist)
+ instructionports.add(port);
+ FabricTree instructions =
+ new FabricTree((Port[])instructionports.toArray(new Port[0]),
+ "horn",
+ "instruction");
+
+ ArrayList inputports = new ArrayList<Port>();
+ for(Ship ship : shiplist)
+ for(Port port : ship.portlist)
+ if (port instanceof Inbox)
+ inputports.add(port);
+ FabricTree inputs =
+ new FabricTree((Port[])inputports.toArray(new Port[0]),
+ "horn",
+ "dest");
+
+ ArrayList outputports = new ArrayList<Port>();
+ for(Ship ship : shiplist)
+ for(Port port : ship.portlist)
+ if (port instanceof Outbox && !(port.getShip() instanceof DebugShip))
+ outputports.add(port);
+ FabricTree outputs =
+ new FabricTree((Port[])outputports.toArray(new Port[0]),
+ "funnel",
+ "source");
+
+ if (quiet) return;
+ System.out.println("import [balsa.sim.portio]");
+ System.out.println("import [xbit]");
+ System.out.println("import [funnel]");
+ System.out.println("import [horn]");
+ System.out.println("import [par2ser]");
+ System.out.println("import [ser2par]");
+
+ HashSet<Class> added = new HashSet<Class>();
+ for(Ship ship : shiplist)
+ if (!added.contains(ship.getClass())) {
+ added.add(ship.getClass());
+ System.out.println("import ["+ship.getBalsaName()+"]");
+ }
+
+ System.out.println("procedure fabric(input top_in:XBit; output top_out:XBit)");
+ System.out.println("is");
+ System.out.println(" channel source_debug_out : XBit");
+ instructions.dumpChannels(true);
+ outputs.dumpChannels(true);
+ inputs.dumpChannels(true);
+ System.out.println("begin");
+ System.out.println(" loop source -> dest end");
+ System.out.println(" || loop top_in -> instruction end");
+ System.out.println(" || loop source_debug_out -> top_out end");
+ System.out.println("");
+ instructions.dumpChannels(false);
+ System.out.println("");
+ outputs.dumpChannels(false);
+ System.out.println("");
+ inputs.dumpChannels(false);
+ System.out.println("");
+ for(Ship ship : shiplist) {
+ System.out.print(" || ");
+ System.out.print(ship.getBalsaName());
+ System.out.print("(");
+ boolean first = true;
+ for(Port port : ship.portlist) {
+ if (!first) System.out.print(", ");
+ first = false;
+ System.out.print("instruction_"+port.getShip().getName()+"_"+port.getName());
+ System.out.print(",");
+ if (port instanceof Inbox)
+ System.out.print("dest_"+port.getShip().getName()+"_"+port.getName());
+ else
+ System.out.print("source_"+port.getShip().getName()+"_"+port.getName());
+ System.out.print(" ");
+ }
+ System.out.println(")");
+ }
+ System.out.println("end");
+ }
+
+ private static class FabricTree {
+ int master_idx = 1;
+ String prefix;
+ Node root;
+ public void dumpChannels(boolean decl) { root.dumpChannels(0, decl); }
+ public FabricTree(Port[] ports, String component, String prefix) {
+ this.prefix = prefix;
+ root = (Node)mkNode("", component, ports, 0, ports.length, 0, 0);
+ }
+ private Object mkNode(String name, String component, Port[] ports, int start, int end, int addr, int bits) {
+ if (end-start == 0) return null;
+ if (end-start == 1) {
+ Port p = ports[start];
+ if (prefix.equals("instruction")) {
+ p.instr_addr = addr;
+ p.instr_bits = bits;
+ } else {
+ p.addr = addr;
+ p.bits = bits;
+ }
+ return p;
+ }
+ int len = end-start;
+ return new Node(name,
+ component,
+ mkNode(name+"_0", component, ports, start, start+len/2, (addr<<1)|0, bits+1),
+ mkNode(name+"_1", component, ports, start+len/2, end, (addr<<1)|1, bits+1),
+ addr,
+ bits);
+ }
+ private String describe(String prefix, Object o) {
+ if (o==null) return null;
+ if (o instanceof Port) {
+ Port p = (Port)o;
+ return prefix+"_"+p.getShip().getName()+"_"+p.getName();
+ }
+ if (o instanceof Node) {
+ return ((Node)o).describe(prefix);
+ }
+ return null;
+ }
+ private class Node {
+ Object left;
+ Object right;
+ String name;
+ String component;
+ int addr;
+ int bits;
+ public Node(String name, String component, Object left, Object right, int addr, int bits) {
+ this.left = left;
+ this.right = right;
+ this.name = name;
+ this.component = component;
+ this.addr = addr;
+ this.bits = bits;
+ }
+ public void dumpChannels(int indentamount, boolean decl) {
+ String indent = "";
+ for(int i=0; i<indentamount; i++) indent += " ";
+ if (decl) {
+ System.out.println(" channel "+indent+describe(prefix)+" : XBit");
+ } else {
+ System.out.println(" || "+indent+
+ component+"("+describe(prefix)+
+ ", "+FabricTree.this.describe(prefix, left)+
+ ", "+FabricTree.this.describe(prefix, right)+")");
+ }
+ dumpChannels(left, indentamount+1, decl);
+ dumpChannels(right, indentamount+1, decl);
+ }
+ public void dumpChannels(Object o, int indentamount, boolean decl) {
+ if (o==null) return;
+ if (o instanceof Node) {
+ ((Node)o).dumpChannels(indentamount, decl);
+ } else {
+ String indent = "";
+ for(int i=0; i<indentamount; i++) indent += " ";
+ if (decl)
+ System.out.println(" channel "+indent+FabricTree.this.describe(prefix,o)+" :XBit");
+ }
+ }
+ public String describe(String prefix) {
+ return prefix+name;
+ }
+ }
+ }
+