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 dumpCode() {
21 throw new RuntimeException("not implemented");
24 public void dispatch(Instruction i, long address) {
26 if (i instanceof Instruction.Executable) {
27 InterpreterBenkoBox sourceBenkoBox = resolve(((Instruction.Executable)i).benkoBox);
28 if (!(sourceBenkoBox instanceof InstructionPort))
29 throw new RuntimeException(sourceBenkoBox + " is not an InstructionPort!");
30 ((InstructionPort)sourceBenkoBox).addInstruction(((Instruction.Executable)i));
32 } else if (i instanceof Instruction.Literal.CodeBagDescriptor) {
34 Instruction.Literal.CodeBagDescriptor cbd = (Instruction.Literal.CodeBagDescriptor)i;
35 dispatchCodeBag(cbd.offset+address, cbd.size);
37 } else if (i instanceof Instruction.Literal.Absolute) {
38 InterpreterBenkoBox destBenkoBox = resolve(((Instruction.Literal.Absolute)i).dest);
39 Log.data(((Instruction.Literal.Absolute)i).value+"", null, destBenkoBox);
40 destBenkoBox.addDataFromFabric((int)((Instruction.Literal.Absolute)i).value);
42 } else if (i instanceof Instruction.Kill) {
43 InterpreterBenkoBox benkoBox = resolve(((Instruction.Kill)i).benkoBox);
44 if (!(benkoBox instanceof InstructionPort))
45 throw new RuntimeException(benkoBox + " is not an InstructionPort!");
46 ((InstructionPort)benkoBox).kill(((Instruction.Kill)i).count);
49 throw new Error("unsupported: " + i.getClass().getName());
53 /** some "halt ship" can turn this on to stop the interpreter */
54 public boolean halt = false;
56 public int[] mem = new int[0];
58 public Instruction[] instructions = null;
59 public ArrayList<String> imports = new ArrayList<String>();
61 private static String getUniqueName(Ship ship) {
62 return ship.getType() + ship.getOrdinal();
65 public ArrayList<InterpreterShip> shiplist = new ArrayList<InterpreterShip>();
66 public HashMap<String,InterpreterShip> ships = new HashMap<String,InterpreterShip>();
68 /** read a machine-formatted instruction from a file (into a Java object) */
69 public Instruction readInstruction(DataInputStream is) throws IOException {
74 public void writeInstruction(DataOutputStream os, Instruction d) throws IOException {
75 if (d instanceof Instruction.Executable) {
76 Instruction.Executable inst = (Instruction.Executable)d;
78 InterpreterBenkoBox dest = resolve(inst.dest);
79 long instr = dest==null ? 0 : (dest.addr << 1);
81 instr |= (((long)inst.count) << (11+1));
82 if (inst.tokenIn) instr |= (1L << (11+1+7+0));
83 if (inst.dataOut) instr |= (1L << (11+1+7+1));
84 if (inst.latch) instr |= (1L << (11+1+7+2));
85 if (inst.dataIn) instr |= (1L << (11+1+7+3));
86 if (inst.tokenOut) instr |= (1L << (11+1+7+4));
87 instr |= ((long)resolve(inst.benkoBox).instr_addr) << (11+5+7+1);
89 out |= ((InterpreterBenkoBox)ships.get("command").getBenkoBox("data")).addr;
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);
97 } else if (d instanceof Instruction.Literal.Absolute) {
98 Instruction.Literal.Absolute ld = (Instruction.Literal.Absolute)d;
100 out |= resolve(ld.dest).addr;
101 out |= ((long)ld.value) << 11;
102 dump(os, (out >> (5*8)) & 0xff);
103 dump(os, (out >> (4*8)) & 0xff);
104 dump(os, (out >> (3*8)) & 0xff);
105 dump(os, (out >> (2*8)) & 0xff);
106 dump(os, (out >> (1*8)) & 0xff);
107 dump(os, (out >> (0*8)) & 0xff);
110 public void dump(OutputStream os, long data_) throws IOException {
111 int data = (int)data_;
112 os.write((byte)data);
113 System.out.println(data);
116 public Iterator<Ship> iterator() {
117 return (Iterator<Ship>)(Object)shiplist.iterator();
120 public void dispatchCodeBag(long base, long size) {
121 for(long i=base; i<base+size; i++)
122 dispatch(instructions[(int)i], i);
126 Instruction.Literal.CodeBagDescriptor cbl =
127 (Instruction.Literal.CodeBagDescriptor)instructions[0];
128 dispatchCodeBag(cbl.offset+0, cbl.size);
131 for(InterpreterShip ship : ships.values())
132 for(int j=0; j<10; j++)
135 // run the ships a bit longer for good measure
136 for(int i=0; i<100; i++)
137 for(InterpreterShip ship : ships.values())
138 for(int j=0; j<10; j++)
141 // check the state of the ships
142 for(InterpreterShip ship : ships.values())
145 Log.println(Log.yellow(" DONE: ====== FLEET is halted. Have a nice day. ======"));
148 public void dumpMem() {
149 Log.print(Log.cyan(" MEMORY: "));
150 for(int i=0; i<mem.length; i++) {
151 if ((i%10)==0 && i!=0) Log.print(Log.cyan(" "));
152 Log.print(Log.cyan(mem[i] + " "));
153 if ((i%10)==9 && i!=mem.length-1) Log.println("");
158 public void writeMem(int addr, int data) {
159 if (addr >= mem.length) {
160 int[] mem2 = new int[addr*2+1];
161 System.arraycopy(mem, 0, mem2, 0, mem2.length);
167 public InterpreterShip getShip(String name) {
168 InterpreterShip s = ships.get(name);
169 if (s == null) throw new RuntimeException("unknown ship \""+name+"\"");
173 public InterpreterShip tryCreate(String classname, String shipname) {
175 Class c = Class.forName(classname);
176 Constructor con = c.getConstructor(new Class[] { Interpreter.class, String.class });
177 InterpreterShip ret = (InterpreterShip)con.newInstance(new Object[] { this, shipname });
178 ships.put(shipname, ret);
181 } catch (Exception e) {
186 public void sendToken(InterpreterBenkoBox source, InterpreterBenkoBox dest) {
187 Log.token(source, dest);
188 dest.addTokenFromFabric();
191 public void sendData(InterpreterBenkoBox source, int data, InterpreterBenkoBox dest) {
192 Log.data(data+"", source, dest);
193 dest.addDataFromFabric(data);
196 public void dumpFabric(boolean quiet) {
197 // FIXME: this is really ugly: the order of port declarations in
198 // the XXXShip.java file must match the order in the .balsa file!
200 ArrayList instructionports = new ArrayList<InterpreterBenkoBox>();
201 for(InterpreterShip ship : shiplist)
202 for(BenkoBox port : ship.getBenkoBoxes())
203 if (!((InterpreterBenkoBox)port).special())
204 instructionports.add(port);
205 FabricTree instructions =
206 new FabricTree((InterpreterBenkoBox[])instructionports.toArray(new InterpreterBenkoBox[0]),
210 ArrayList inputports = new ArrayList<InterpreterBenkoBox>();
211 for(InterpreterShip ship : shiplist)
212 for(BenkoBox port : ship.getBenkoBoxes())
213 if (!((InterpreterBenkoBox)port).special())
214 inputports.add(port);
216 new FabricTree((InterpreterBenkoBox[])inputports.toArray(new InterpreterBenkoBox[0]),
220 ArrayList outputports = new ArrayList<InterpreterBenkoBox>();
221 for(InterpreterShip ship : shiplist)
222 for(BenkoBox port : ship.getBenkoBoxes())
223 if (!((InterpreterBenkoBox)port).special())
224 outputports.add(port);
226 new FabricTree((InterpreterBenkoBox[])outputports.toArray(new InterpreterBenkoBox[0]),
231 System.out.println("`include \"macros.v\"");
233 HashSet<Class> added = new HashSet<Class>();
234 for(Ship ship : shiplist)
235 if (!added.contains(ship.getClass())) {
236 added.add(ship.getClass());
237 System.out.println("import ["+ship.getBalsaName()+"]");
240 System.out.println("module fabric(clk, top_r, top_a, top,");
241 System.out.println(" data_Debug0_out_r, data_Debug0_out_a, data_Debug0_out);");
242 System.out.println(" input clk;");
243 System.out.println(" input top_r;");
244 System.out.println(" output top_a;");
245 System.out.println(" input [(`PACKET_WIDTH-1):0] top;");
246 System.out.println(" output data_Debug0_out_r;");
247 System.out.println(" input data_Debug0_out_a;");
248 System.out.println(" output [(`PACKET_WIDTH-1):0] data_Debug0_out;");
249 System.out.println(" wire [(`INSTRUCTION_WIDTH-1):0] data_Command0_out;");
250 System.out.println();
252 System.out.println();
254 instructions.dumpChannels(true);
255 outputs.dumpChannels(true);
256 inputs.dumpChannels(true);
257 for(InterpreterShip ship : shiplist)
258 for(BenkoBox port : ship.getBenkoBoxes()) {
259 if (ship instanceof Command && port instanceof Outbox) continue;
260 System.out.println(" wire [(`PACKET_WIDTH-1):0] data_"+getUniqueName(ship)+"_"+port.getName()+";");
263 System.out.println("");
264 instructions.dumpChannels(false);
265 System.out.println("");
266 outputs.dumpChannels(false);
267 System.out.println("");
268 inputs.dumpChannels(false);
269 System.out.println("");
270 for(InterpreterShip ship : shiplist) {
271 System.out.print(ship.getClass().getSimpleName().toLowerCase());
272 System.out.print(" ");
273 System.out.print("krunk"+(krunk++));
274 System.out.print("(clk, ");
275 boolean first = true;
276 for(BenkoBox port : ship.getBenkoBoxes()) {
277 if (!first) System.out.print(", ");
279 System.out.print("data_"+getUniqueName(port.getShip())+"_"+port.getName()+"_r, ");
280 System.out.print("data_"+getUniqueName(port.getShip())+"_"+port.getName()+"_a, ");
281 System.out.print("data_"+getUniqueName(port.getShip())+"_"+port.getName());
282 System.out.print(" ");
284 System.out.println(");");
286 for(BenkoBox port : ship.getBenkoBoxes()) {
287 if (((InterpreterBenkoBox)port).special()) continue;
288 if (port instanceof Inbox) {
289 if (((InterpreterBenkoBox)port).noInbox())
290 System.out.print("stupidinbox");
292 System.out.print("inbox");
294 System.out.print("outbox");
296 System.out.print(" krunk"+(krunk++)+"(clk, ");
297 System.out.print("instruction_"+getUniqueName(port.getShip())+"_"+port.getName()+"_r, ");
298 System.out.print("instruction_"+getUniqueName(port.getShip())+"_"+port.getName()+"_a, ");
299 System.out.print("instruction_"+getUniqueName(port.getShip())+"_"+port.getName()+", ");
300 System.out.print("dest_"+getUniqueName(port.getShip())+"_"+port.getName()+"_r, ");
301 System.out.print("dest_"+getUniqueName(port.getShip())+"_"+port.getName()+"_a, ");
302 System.out.print("dest_"+getUniqueName(port.getShip())+"_"+port.getName()+", ");
303 System.out.print("source_"+getUniqueName(port.getShip())+"_"+port.getName()+"_r, ");
304 System.out.print("source_"+getUniqueName(port.getShip())+"_"+port.getName()+"_a, ");
305 System.out.print("source_"+getUniqueName(port.getShip())+"_"+port.getName()+", ");
306 System.out.print("data_"+getUniqueName(port.getShip())+"_"+port.getName()+"_r, ");
307 System.out.print("data_"+getUniqueName(port.getShip())+"_"+port.getName()+"_a, ");
308 System.out.print("data_"+getUniqueName(port.getShip())+"_"+port.getName());
309 System.out.print(");");
310 System.out.println();
314 System.out.println("funnel topfun(clk, dest_r, dest_a, dest, source_r, source_a, source, top_r, top_a, top);");
315 System.out.println("");
316 System.out.println(" assign instruction_r = data_Command0_out_r;");
317 System.out.println(" assign data_Command0_out_a = instruction_a;");
318 System.out.println(" assign instruction = data_Command0_out;");
319 System.out.println("endmodule");
322 private static class FabricTree {
326 public void dumpChannels(boolean decl) { root.dumpChannels(0, decl); }
327 public FabricTree(InterpreterBenkoBox[] ports, String component, String prefix) {
328 this.prefix = prefix;
329 root = (Node)mkNode("", component, ports, 0, ports.length, 0, 0);
331 private Object mkNode(String name, String component, InterpreterBenkoBox[] ports,
332 int start, int end, int addr, int bits) {
333 if (end-start == 0) return null;
334 if (end-start == 1) {
335 InterpreterBenkoBox p = ports[start];
336 if (prefix.equals("instruction")) {
346 return new Node(name,
348 mkNode(name+"_0", component, ports, start, start+len/2, addr, bits+1),
349 mkNode(name+"_1", component, ports, start+len/2, end, addr | (1 << bits), bits+1),
353 private String describe(String prefix, Object o) {
354 if (o==null) return null;
355 if (o instanceof InterpreterBenkoBox) {
356 InterpreterBenkoBox p = (InterpreterBenkoBox)o;
357 return prefix+"_"+getUniqueName(p.getShip())+"_"+p.getName();
359 if (o instanceof Node) {
360 return ((Node)o).describe(prefix);
371 public Node(String name, String component, Object left, Object right, int addr, int bits) {
375 this.component = component;
379 public void dumpChannels(int indentamount, boolean decl) {
381 for(int i=0; i<indentamount; i++) indent += " ";
383 String n = describe(prefix).startsWith("instruction")
384 ? "[(`INSTRUCTION_WIDTH-1):0]" : "[(`PACKET_WIDTH-1):0]";
385 System.out.println(" wire "+n+" "+indent+describe(prefix)+";");
387 System.out.println(" "+indent+
389 "krunk"+(krunk++)+"(clk, "+
390 describe(prefix)+"_r, "+
391 describe(prefix)+"_a, "+
392 describe(prefix)+", "+
393 FabricTree.this.describe(prefix, left)+"_r, "+
394 FabricTree.this.describe(prefix, left)+"_a, "+
395 FabricTree.this.describe(prefix, left)+", "+
396 FabricTree.this.describe(prefix, right)+"_r, "+
397 FabricTree.this.describe(prefix, right)+"_a, "+
398 FabricTree.this.describe(prefix, right)+
401 dumpChannels(left, indentamount+1, decl);
402 dumpChannels(right, indentamount+1, decl);
404 public void dumpChannels(Object o, int indentamount, boolean decl) {
406 if (o instanceof Node) {
407 ((Node)o).dumpChannels(indentamount, decl);
410 for(int i=0; i<indentamount; i++) indent += " ";
412 String n = FabricTree.this.describe(prefix,o).startsWith("instruction")
413 ? "[(`INSTRUCTION_WIDTH-1):0]" : "[(`PACKET_WIDTH-1):0]";
414 System.out.println(" wire "+n+" "+indent+FabricTree.this.describe(prefix,o)+";");
418 public String describe(String prefix) {
423 public static int krunk=0;
425 public int computeOffset(int origin, int target) { return target - origin; }
426 public int computeTarget(int origin, int offset) { return origin + offset; }