1 package edu.berkeley.fleet.interpreter;
2 import edu.berkeley.fleet.api.*;
4 import edu.berkeley.fleet.api.*;
5 import edu.berkeley.fleet.*;
6 import java.lang.reflect.*;
7 import edu.berkeley.sbp.chr.*;
8 import edu.berkeley.sbp.misc.*;
9 import edu.berkeley.sbp.meta.*;
10 import edu.berkeley.sbp.bind.*;
11 import edu.berkeley.sbp.util.*;
14 import edu.berkeley.fleet.ships.*;
16 public class Interpreter extends Fleet implements Iterable<Ship> {
18 public InterpreterBenkoBox resolve(edu.berkeley.fleet.api.BenkoBox bb) { return (InterpreterBenkoBox)bb; }
20 public void dispatch(Instruction i) {
22 if (i instanceof Instruction.Executable) {
23 InterpreterBenkoBox sourceBenkoBox = resolve(((Instruction.Executable)i).benkoBox);
24 if (!(sourceBenkoBox instanceof InstructionPort))
25 throw new RuntimeException(sourceBenkoBox + " is not an InstructionPort!");
26 ((InstructionPort)sourceBenkoBox).addInstruction(((Instruction.Executable)i));
28 } else if (i instanceof Instruction.Literal.Absolute) {
29 InterpreterBenkoBox destBenkoBox = resolve(((Instruction.Literal.Absolute)i).dest);
30 Log.data(((Instruction.Literal.Absolute)i).value+"", null, destBenkoBox);
31 destBenkoBox.addDataFromFabric((int)((Instruction.Literal.Absolute)i).value);
33 } else if (i instanceof Instruction.Kill) {
34 InterpreterBenkoBox benkoBox = resolve(((Instruction.Kill)i).benkoBox);
35 if (!(benkoBox instanceof InstructionPort))
36 throw new RuntimeException(benkoBox + " is not an InstructionPort!");
37 ((InstructionPort)benkoBox).kill(((Instruction.Kill)i).count);
40 throw new Error("unsupported!");
44 /** some "halt ship" can turn this on to stop the interpreter */
45 public boolean halt = false;
47 public int[] mem = new int[0];
48 public ArrayList<String> imports = new ArrayList<String>();
50 private static String getUniqueName(Ship ship) {
51 return ship.getType() + ship.getOrdinal();
54 public ArrayList<InterpreterShip> shiplist = new ArrayList<InterpreterShip>();
55 public HashMap<String,InterpreterShip> ships = new HashMap<String,InterpreterShip>();
57 /** read a machine-formatted instruction from a file (into a Java object) */
58 public Instruction readInstruction(DataInputStream is) throws IOException {
63 public void writeInstruction(DataOutputStream os, Instruction d) throws IOException {
64 if (d instanceof Instruction.Executable) {
65 Instruction.Executable inst = (Instruction.Executable)d;
67 InterpreterBenkoBox dest = resolve(inst.dest);
68 long instr = dest==null ? 0 : (dest.addr << 1);
70 instr |= (((long)inst.count) << (11+1));
71 if (inst.tokenIn) instr |= (1L << (11+1+7+0));
72 if (inst.dataOut) instr |= (1L << (11+1+7+1));
73 if (inst.latch) instr |= (1L << (11+1+7+2));
74 if (inst.dataIn) instr |= (1L << (11+1+7+3));
75 if (inst.tokenOut) instr |= (1L << (11+1+7+4));
76 instr |= ((long)resolve(inst.benkoBox).instr_addr) << (11+5+7+1);
78 out |= ((InterpreterBenkoBox)ships.get("command").getBenkoBox("data")).addr;
80 dump(os, (out >> (5*8)) & 0xff);
81 dump(os, (out >> (4*8)) & 0xff);
82 dump(os, (out >> (3*8)) & 0xff);
83 dump(os, (out >> (2*8)) & 0xff);
84 dump(os, (out >> (1*8)) & 0xff);
85 dump(os, (out >> (0*8)) & 0xff);
86 } else if (d instanceof Instruction.Literal.Absolute) {
87 Instruction.Literal.Absolute ld = (Instruction.Literal.Absolute)d;
89 out |= resolve(ld.dest).addr;
90 out |= ((long)ld.value) << 11;
91 dump(os, (out >> (5*8)) & 0xff);
92 dump(os, (out >> (4*8)) & 0xff);
93 dump(os, (out >> (3*8)) & 0xff);
94 dump(os, (out >> (2*8)) & 0xff);
95 dump(os, (out >> (1*8)) & 0xff);
96 dump(os, (out >> (0*8)) & 0xff);
99 public void dump(OutputStream os, long data_) throws IOException {
100 int data = (int)data_;
101 os.write((byte)data);
102 System.out.println(data);
105 public Iterator<Ship> iterator() {
106 return (Iterator<Ship>)(Object)shiplist.iterator();
111 for(InterpreterShip ship : ships.values())
112 for(int j=0; j<10; j++)
115 // run the ships a bit longer for good measure
116 for(int i=0; i<100; i++)
117 for(InterpreterShip ship : ships.values())
118 for(int j=0; j<10; j++)
121 // check the state of the ships
122 for(InterpreterShip ship : ships.values())
125 Log.println(Log.yellow(" DONE: ====== FLEET is halted. Have a nice day. ======"));
128 public void dumpMem() {
129 Log.print(Log.cyan(" MEMORY: "));
130 for(int i=0; i<mem.length; i++) {
131 if ((i%10)==0 && i!=0) Log.print(Log.cyan(" "));
132 Log.print(Log.cyan(mem[i] + " "));
133 if ((i%10)==9 && i!=mem.length-1) Log.println("");
138 public void writeMem(int addr, int data) {
139 if (addr >= mem.length) {
140 int[] mem2 = new int[addr*2+1];
141 System.arraycopy(mem, 0, mem2, 0, mem2.length);
147 public InterpreterShip getShip(String name) {
148 InterpreterShip s = ships.get(name);
149 if (s == null) throw new RuntimeException("unknown ship \""+name+"\"");
153 public InterpreterShip tryCreate(String classname, String shipname) {
155 Class c = Class.forName(classname);
156 Constructor con = c.getConstructor(new Class[] { Interpreter.class, String.class });
157 InterpreterShip ret = (InterpreterShip)con.newInstance(new Object[] { this, shipname });
158 ships.put(shipname, ret);
161 } catch (Exception e) {
166 public void sendToken(InterpreterBenkoBox source, InterpreterBenkoBox dest) {
167 Log.token(source, dest);
168 dest.addTokenFromFabric();
171 public void sendData(InterpreterBenkoBox source, int data, InterpreterBenkoBox dest) {
172 Log.data(data+"", source, dest);
173 dest.addDataFromFabric(data);
176 public void dumpFabric(boolean quiet) {
177 // FIXME: this is really ugly: the order of port declarations in
178 // the XXXShip.java file must match the order in the .balsa file!
180 ArrayList instructionports = new ArrayList<InterpreterBenkoBox>();
181 for(InterpreterShip ship : shiplist)
182 for(BenkoBox port : ship.getBenkoBoxes())
183 if (!((InterpreterBenkoBox)port).special())
184 instructionports.add(port);
185 FabricTree instructions =
186 new FabricTree((InterpreterBenkoBox[])instructionports.toArray(new InterpreterBenkoBox[0]),
190 ArrayList inputports = new ArrayList<InterpreterBenkoBox>();
191 for(InterpreterShip ship : shiplist)
192 for(BenkoBox port : ship.getBenkoBoxes())
193 if (!((InterpreterBenkoBox)port).special())
194 inputports.add(port);
196 new FabricTree((InterpreterBenkoBox[])inputports.toArray(new InterpreterBenkoBox[0]),
200 ArrayList outputports = new ArrayList<InterpreterBenkoBox>();
201 for(InterpreterShip ship : shiplist)
202 for(BenkoBox port : ship.getBenkoBoxes())
203 if (!((InterpreterBenkoBox)port).special())
204 outputports.add(port);
206 new FabricTree((InterpreterBenkoBox[])outputports.toArray(new InterpreterBenkoBox[0]),
211 System.out.println("`include \"macros.v\"");
213 HashSet<Class> added = new HashSet<Class>();
214 for(Ship ship : shiplist)
215 if (!added.contains(ship.getClass())) {
216 added.add(ship.getClass());
217 System.out.println("import ["+ship.getBalsaName()+"]");
220 System.out.println("module fabric(clk, top_r, top_a, top,");
221 System.out.println(" data_debug_out_r, data_debug_out_a, data_debug_out);");
222 System.out.println(" input clk;");
223 System.out.println(" input top_r;");
224 System.out.println(" output top_a;");
225 System.out.println(" input [(`PACKET_WIDTH-1):0] top;");
226 System.out.println(" output data_debug_out_r;");
227 System.out.println(" input data_debug_out_a;");
228 System.out.println(" output [(`PACKET_WIDTH-1):0] data_debug_out;");
229 System.out.println(" wire [(`INSTRUCTION_WIDTH-1):0] data_command_out;");
230 System.out.println();
232 System.out.println();
234 instructions.dumpChannels(true);
235 outputs.dumpChannels(true);
236 inputs.dumpChannels(true);
237 for(InterpreterShip ship : shiplist)
238 for(BenkoBox port : ship.getBenkoBoxes()) {
239 if (ship instanceof Command && port instanceof Outbox) continue;
240 System.out.println(" wire [(`PACKET_WIDTH-1):0] data_"+getUniqueName(ship)+"_"+port.getName()+";");
243 System.out.println("");
244 instructions.dumpChannels(false);
245 System.out.println("");
246 outputs.dumpChannels(false);
247 System.out.println("");
248 inputs.dumpChannels(false);
249 System.out.println("");
250 for(InterpreterShip ship : shiplist) {
251 System.out.print(ship.getClass().getSimpleName().toLowerCase());
252 System.out.print(" ");
253 System.out.print("krunk"+(krunk++));
254 System.out.print("(clk, ");
255 boolean first = true;
256 for(BenkoBox port : ship.getBenkoBoxes()) {
257 if (!first) System.out.print(", ");
259 System.out.print("data_"+getUniqueName(port.getShip())+"_"+port.getName()+"_r, ");
260 System.out.print("data_"+getUniqueName(port.getShip())+"_"+port.getName()+"_a, ");
261 System.out.print("data_"+getUniqueName(port.getShip())+"_"+port.getName());
262 System.out.print(" ");
264 System.out.println(");");
266 for(BenkoBox port : ship.getBenkoBoxes()) {
267 if (((InterpreterBenkoBox)port).special()) continue;
268 if (port instanceof Inbox) {
269 if (((InterpreterBenkoBox)port).noInbox())
270 System.out.print("stupidinbox");
272 System.out.print("inbox");
274 System.out.print("outbox");
276 System.out.print(" krunk"+(krunk++)+"(clk, ");
277 System.out.print("instruction_"+getUniqueName(port.getShip())+"_"+port.getName()+"_r, ");
278 System.out.print("instruction_"+getUniqueName(port.getShip())+"_"+port.getName()+"_a, ");
279 System.out.print("instruction_"+getUniqueName(port.getShip())+"_"+port.getName()+", ");
280 System.out.print("dest_"+getUniqueName(port.getShip())+"_"+port.getName()+"_r, ");
281 System.out.print("dest_"+getUniqueName(port.getShip())+"_"+port.getName()+"_a, ");
282 System.out.print("dest_"+getUniqueName(port.getShip())+"_"+port.getName()+", ");
283 System.out.print("source_"+getUniqueName(port.getShip())+"_"+port.getName()+"_r, ");
284 System.out.print("source_"+getUniqueName(port.getShip())+"_"+port.getName()+"_a, ");
285 System.out.print("source_"+getUniqueName(port.getShip())+"_"+port.getName()+", ");
286 System.out.print("data_"+getUniqueName(port.getShip())+"_"+port.getName()+"_r, ");
287 System.out.print("data_"+getUniqueName(port.getShip())+"_"+port.getName()+"_a, ");
288 System.out.print("data_"+getUniqueName(port.getShip())+"_"+port.getName());
289 System.out.print(");");
290 System.out.println();
294 System.out.println("funnel topfun(clk, dest_r, dest_a, dest, source_r, source_a, source, top_r, top_a, top);");
295 System.out.println("");
296 System.out.println(" assign instruction_r = data_command_out_r;");
297 System.out.println(" assign data_command_out_a = instruction_a;");
298 System.out.println(" assign instruction = data_command_out;");
299 System.out.println("endmodule");
302 private static class FabricTree {
306 public void dumpChannels(boolean decl) { root.dumpChannels(0, decl); }
307 public FabricTree(InterpreterBenkoBox[] ports, String component, String prefix) {
308 this.prefix = prefix;
309 root = (Node)mkNode("", component, ports, 0, ports.length, 0, 0);
311 private Object mkNode(String name, String component, InterpreterBenkoBox[] ports, int start, int end, int addr, int bits) {
312 if (end-start == 0) return null;
313 if (end-start == 1) {
314 InterpreterBenkoBox p = ports[start];
315 if (prefix.equals("instruction")) {
325 return new Node(name,
327 mkNode(name+"_0", component, ports, start, start+len/2, addr, bits+1),
328 mkNode(name+"_1", component, ports, start+len/2, end, addr | (1 << bits), bits+1),
332 private String describe(String prefix, Object o) {
333 if (o==null) return null;
334 if (o instanceof InterpreterBenkoBox) {
335 InterpreterBenkoBox p = (InterpreterBenkoBox)o;
336 return prefix+"_"+getUniqueName(p.getShip())+"_"+p.getName();
338 if (o instanceof Node) {
339 return ((Node)o).describe(prefix);
350 public Node(String name, String component, Object left, Object right, int addr, int bits) {
354 this.component = component;
358 public void dumpChannels(int indentamount, boolean decl) {
360 for(int i=0; i<indentamount; i++) indent += " ";
362 String n = describe(prefix).startsWith("instruction") ? "[(`INSTRUCTION_WIDTH-1):0]" : "[(`PACKET_WIDTH-1):0]";
363 System.out.println(" wire "+n+" "+indent+describe(prefix)+";");
365 System.out.println(" "+indent+
367 "krunk"+(krunk++)+"(clk, "+
368 describe(prefix)+"_r, "+
369 describe(prefix)+"_a, "+
370 describe(prefix)+", "+
371 FabricTree.this.describe(prefix, left)+"_r, "+
372 FabricTree.this.describe(prefix, left)+"_a, "+
373 FabricTree.this.describe(prefix, left)+", "+
374 FabricTree.this.describe(prefix, right)+"_r, "+
375 FabricTree.this.describe(prefix, right)+"_a, "+
376 FabricTree.this.describe(prefix, right)+
379 dumpChannels(left, indentamount+1, decl);
380 dumpChannels(right, indentamount+1, decl);
382 public void dumpChannels(Object o, int indentamount, boolean decl) {
384 if (o instanceof Node) {
385 ((Node)o).dumpChannels(indentamount, decl);
388 for(int i=0; i<indentamount; i++) indent += " ";
390 String n = FabricTree.this.describe(prefix,o).startsWith("instruction")
391 ? "[(`INSTRUCTION_WIDTH-1):0]" : "[(`PACKET_WIDTH-1):0]";
392 System.out.println(" wire "+n+" "+indent+FabricTree.this.describe(prefix,o)+";");
396 public String describe(String prefix) {
401 public static int krunk=0;