cp = -cp fleet.jar
java = java -Xmx500m
-run: fleet.jar
- $(java) $(cp) $(interpreter_class)
+run: fleet.jar; $(java) $(cp) $(interpreter_class)
-fleet.jar: $(shell find src -name \*.java) src/edu/berkeley/fleet/assembler/fleet.g
+fleet.jar: $(shell find src -name \*.java) $(shell find ships -name \*.ship) src/edu/berkeley/fleet/assembler/fleet.g
mkdir -p build/class/edu/berkeley/fleet/assembler/
cp src/edu/berkeley/fleet/assembler/fleet.g build/class/edu/berkeley/fleet/assembler/
javac -cp lib/edu.berkeley.sbp.jar -d build/class/ $(shell find src -name \*.java)
- cd build/class/; jar xvf ../../lib/edu.berkeley.sbp.jar
+ cd build/class/; jar xf ../../lib/edu.berkeley.sbp.jar
+ for A in `find ships -name \*.ship`;\
+ do java -cp build/class edu.berkeley.fleet.Main expand $$A;\
+ done
+ javac -cp build/class:lib/edu.berkeley.sbp.jar -d build/class/ `find build/java -name \*.java`
echo 'Main-Class: edu.berkeley.fleet.Main' > build/class/manifest
- cd build/class/; jar cvmf manifest ../../$@ .
+ cd build/class/; jar cmf manifest ../../$@ .
## Slipway ####################################################################################
verilog_files = $(shell find src -name \*.v)
verilog_files += $(shell find src -name \*.inc)
-runfpga: fleet.jar
- mkdir -p build
- $(java) $(cp) $(interpreter_class) --dump-code
- $(java) $(cp) edu.berkeley.fleet.slipway.Client superbowl.bit < build/fleet.bin
+runfpga: fleet.jar; $(java) -jar fleet.jar target=fpga run
mrunfpga: fleet.jar build/main.bit
mkdir -p build
$(java) $(cp) $(interpreter_class) --dump-code
rsync -zare ssh --progress --verbose build/main.bit root@bee441.cs.berkeley.edu:/var/slipway/megacz.bit
- $(java) $(cp) edu.berkeley.fleet.slipway.Client megacz.bit < build/fleet.bin
+ #bitfile option doesn't work
+ #$(java) -jar fleet.jar bitfile=megacz.bit target=fpga run
build/fabric.v: $(verilog_files) src/edu/berkeley/fleet/slipway/Slipway.java
make fleet.jar
# $(xilinx)trce -intstyle ise -e 3 -l 3 -s 6 -xml main main.ncd -o main.twr main.pcf
+doc: fleet.jar
+ $(java) $(cp) edu.berkeley.fleet.doc.Doc < ships/Alu2.ship
+
+test: fleet.jar; $(java) -jar fleet.jar test tests/
+
## API docs ####################################################################################
javadoc:
package edu.berkeley.fleet;
+import edu.berkeley.fleet.api.*;
+import edu.berkeley.fleet.slipway.*;
+import edu.berkeley.fleet.doc.*;
+import edu.berkeley.fleet.interpreter.*;
+import java.io.*;
+import java.util.*;
public class Main {
+ static String command;
+ static HashMap<String,String> options = new HashMap<String,String>();
+ static ArrayList<String> args = new ArrayList<String>();
+
public static void main(String[] s) throws Exception {
if (s.length == 0) {
usage();
System.exit(-1);
}
+ boolean optionsDone = false;
+ for(int i=0; i<s.length; i++) {
+ if (!optionsDone && s[i].indexOf('=') != -1) {
+ options.put(s[i].substring(0, s[i].indexOf('=')),
+ s[i].substring(s[i].indexOf('=')+1));
+
+ } else if (!optionsDone) {
+ optionsDone = true;
+ command = s[i];
+ } else {
+ args.add(s[i]);
+ }
+ }
+
+ String target = options.get("target");
+ Fleet fleet;
+ if ("fpga".equals(target)) {
+ fleet = new Slipway();
+ } else {
+ fleet = new Interpreter.DynamicInterpreter();
+ }
+
+ if (!"true".equals(options.get("verbose")))
+ Log.log = null;
+
+ if (command.equals("run")) {
+ InputStream is;
+ if (args.size()==0) {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ Reader r = new InputStreamReader(System.in);
+ edu.berkeley.fleet.assembler.Main.assemble(fleet, r, baos);
+ is = new ByteArrayInputStream(baos.toByteArray());
+ } else {
+ String filename = args.get(0);
+ if (filename.endsWith(".fa") || filename.endsWith(".fleet")) {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ Reader r = new InputStreamReader(new FileInputStream(args.get(0)));
+ edu.berkeley.fleet.assembler.Main.assemble(fleet, r, baos);
+ is = new ByteArrayInputStream(baos.toByteArray());
+ } else {
+ is = new FileInputStream(args.get(0));
+ }
+ }
+ run(fleet, is);
+
+ } else if (command.equals("expand")) {
+ fleet.expand(new ShipDescription(new BufferedReader(new InputStreamReader(new FileInputStream(args.get(0))))));
+
+ } else if (command.equals("test")) {
+ test(fleet, new File(args.get(0)));
+
+ } else {
+ usage();
+ System.exit(-1);
+ }
+ }
+
+ static void test(Fleet fleet, File f) throws Exception {
+ if (f.isDirectory()) {
+ for(String s : f.list())
+ test(fleet, new File(f.getPath() + File.separatorChar + s));
+ } else if (f.getPath().endsWith(".fleet")) {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ edu.berkeley.fleet.assembler.Main.assemble(fleet, new InputStreamReader(new FileInputStream(f)), baos);
+ FleetProcess fp = fleet.run(baos.toByteArray());
+ try {
+ ArrayList<Long> expect = edu.berkeley.fleet.assembler.Parser.expect;
+ String output = "";
+ // FIXME: check for extraneous stuff at the end
+ String verdict = "[ ]";
+ boolean failed = false;
+ while(true) {
+ if (output.length() > 60 && !failed)
+ output = "..."+output.substring(output.length()-57, output.length());
+ if (expect.size() == 0) verdict = "["+Log.green("PASS")+"]";
+ System.out.print("\r" + verdict + " " + Log.yellow(f.getPath()) + ": " + output);
+ if (failed) break;
+ if (expect.size() == 0) break;
+ long l = fp.readWord();
+ long l2 = expect.remove(0);
+ if (l!=l2) {
+ verdict = "["+Log.red("FAIL")+"]";
+ output += Log.red("0x"+Long.toString(l, 16)) +
+ Log.yellow(" (expected ")+Log.green("0x"+Long.toString(l2, 16))+Log.yellow(")");
+ failed = true;
+ continue;
+ } else {
+ output += ("0x"+Long.toString(l2, 16) + " ");
+ }
+ }
+ System.out.println();
+ } finally {
+ fp.terminate();
+ }
+ }
+ }
+
+ public static void run(Fleet fleet, InputStream is) throws IOException {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ byte[] buf = new byte[1024];
+ while(true) {
+ int numread = is.read(buf, 0, buf.length);
+ if (numread==-1) break;
+ baos.write(buf, 0, numread);
+ }
+ String bitfile = options.get("bitfile");
+ FleetProcess client = fleet.run(baos.toByteArray());
+ /*
+ bitfile==null
+ ? fleet.run(baos.toByteArray())
+ : fleet.run(bitfile, baos.toByteArray());
+ */
+ while(true) {
+ long result = client.readWord();
+ System.err.print(result);
+ System.err.print(" 0x");
+ System.err.print(Long.toString(result, 16));
+ System.err.println();
+ }
}
static void usage() {
System.err.println("");
System.err.println("[options] is in the form key=val; supported keys are:");
System.err.println(" target={igor,fpga,interp}");
+ System.err.println(" bitfile=(hardware image for fpga)");
System.err.println(" verbose={yes,no}");
System.err.println("");
System.err.println("[command] is one of:");
package edu.berkeley.fleet.interpreter;
import java.io.*;
import java.util.*;
+import java.util.concurrent.*;
import java.lang.reflect.*;
import edu.berkeley.fleet.*;
+import edu.berkeley.fleet.doc.*;
import edu.berkeley.fleet.api.*;
import edu.berkeley.fleet.ies44.*;
import edu.berkeley.fleet.ships.*;
-public class Interpreter extends Fleet /*, Fleet.WithDynamicShips*/ {
+public class Interpreter extends Fleet {
/** some "halt ship" can turn this on to stop the interpreter */
public boolean halt = false;
-
public ArrayList<InterpreterShip> shiplist = new ArrayList<InterpreterShip>();
public HashMap<String,InterpreterShip> ships = new HashMap<String,InterpreterShip>();
+ private BlockingQueue<Long> debugStream = new LinkedBlockingQueue<Long>();
+ public int[] mem = new int[0];
- public void go(byte[] instructions) {
- // find the first icache
- Icache icache = null;
- for(Ship ship : this)
- if (ship instanceof Icache) {
- icache = (Icache)ship;
- break;
+ public void debug(long data) {
+ try {
+ if (debugStream != null) {
+ debugStream.put(data);
+ } else {
+ Log.println(Log.invert(" DEBUG: got a datum: " + data+Log.clreol()));
}
-
- // load the icache and take note of the 0-address CBD
- long launch = 0;
- for(int i=0; i<instructions.length; i+=6) {
- long word = 0;
- for(int j=0; j<6; j++)
- word = (word << 8) | (instructions[i+j] & 0xff);
- icache.writeMem(i/6, word);
- if (i==0) launch = word;
+ } catch (Exception e) {
+ throw new RuntimeException(e);
}
+ }
- // dispatch the 0-address CBD
- int base = (int)(launch >> 6);
- base = base & ~(0xffffffff << 18);
- int size = (int)launch;
- size = size & ~(0xffffffff << 6);
- icache.dispatch(base, size);
+ public static class DynamicInterpreter extends Interpreter implements Fleet.WithDynamicShips {
+ }
- while(!halt)
- for(InterpreterShip ship : ships.values())
- for(int j=0; j<10; j++)
- ship._service();
+ public void expand(ShipDescription sd) {
+ try {
+ String filename = (sd.name.charAt(0)+"").toUpperCase() + sd.name.substring(1).toLowerCase();
+ File outf = new File("build/java/edu/berkeley/fleet/ships/"+filename+".java");
+ new File(outf.getParent()).mkdirs();
+ System.err.println("writing to " + outf);
+ FileOutputStream out = new FileOutputStream(outf);
+ PrintWriter pw = new PrintWriter(out);
+
+ pw.println("package edu.berkeley.fleet.ships;");
+ pw.println("import edu.berkeley.fleet.interpreter.*;");
+ pw.println("import edu.berkeley.fleet.api.*;");
+ pw.println("import edu.berkeley.fleet.*;");
+ pw.println("import java.util.*;");
+ pw.println("import java.io.*;");
+ pw.println("");
+ pw.println("public class "+filename+" extends InterpreterShip {");
+ pw.println("");
+ for(ShipDescription.BenkoBox b : sd.benkoBoxes) {
+ if (b.ports.length != 1)
+ throw new RuntimeException("multiple ports not supported");
+ String name = b.ports[0];
+ pw.print(" ");
+ if (!b.tokenOnly && b.inbox) pw.print("DataInbox");
+ if ( b.tokenOnly && b.inbox) pw.print("TokenInbox");
+ if (!b.tokenOnly && !b.inbox) pw.print("DataOutbox");
+ if ( b.tokenOnly && !b.inbox) pw.print("TokenOutbox");
+ pw.print(" box_");
+ pw.print(name);
+ pw.print(" = new ");
+ if (!b.tokenOnly && b.inbox) pw.print("DataInbox");
+ if ( b.tokenOnly && b.inbox) pw.print("TokenInbox");
+ if (!b.tokenOnly && !b.inbox) pw.print("DataOutbox");
+ if ( b.tokenOnly && !b.inbox) pw.print("TokenOutbox");
+ pw.println("(this, \""+name+"\");");
+ }
+ pw.println("");
+ pw.println(" public "+filename+"(Interpreter fleet, String name) { super(fleet, name); }");
+ pw.println("");
+ //pw.println(" public void service() {");
+ pw.println(sd.sections.get("fleeterpreter"));
+ //pw.println("}");
+ pw.println("}");
+ pw.flush();
+ pw.close();
+ } catch (Exception e) { throw new RuntimeException(e); }
+ }
- // run the ships a bit longer for good measure
- for(int i=0; i<100; i++)
- for(InterpreterShip ship : ships.values())
- for(int j=0; j<10; j++)
- ship._service();
+ public FleetProcess run(final byte[] instructions) {
+ try {
+ final FleetProcess fp = new FleetProcess() {
+ public void invokeInstruction(Instruction i) { throw new RuntimeException("not supported"); }
+ public long readWord() {
+ try {
+ return debugStream.take();
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ } }
+ protected void _terminate() {
+ shiplist = new ArrayList<InterpreterShip>();
+ ships = new HashMap<String,InterpreterShip>();
+ debugStream = new LinkedBlockingQueue<Long>();
+ mem = new int[0];
+ }
+ };
+ new Thread() {
+ public void run() {
+ try {
+ go(fp, instructions);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }.start();
+ return fp;
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
- // check the state of the ships
- for(InterpreterShip ship : ships.values())
- ship.shutdown();
+ public void go(FleetProcess fp, byte[] instructions) {
+ try {
+ // find the first icache
+ InterpreterShip iscratch = null;
+ for(Ship ship : this)
+ if (ship.getClass().getSimpleName().equals("Iscratch")) {
+ iscratch = (InterpreterShip)ship;
+ break;
+ }
+ if (iscratch==null)
+ iscratch = (InterpreterShip)Class.forName("edu.berkeley.fleet.ships.Iscratch")
+ .getConstructor(new Class[] { Interpreter.class, String.class })
+ .newInstance(new Object[] { this, "iscratch" });
+ iscratch
+ .getClass()
+ .getMethod("boot", new Class[] { byte[].class })
+ .invoke(iscratch, new Object[] { instructions });
+
+ while(!halt && !fp.isTerminated())
+ for(InterpreterShip ship : ships.values())
+ for(int j=0; j<10; j++)
+ ship._service();
+
+ // run the ships a bit longer for good measure
+ for(int i=0; i<100; i++)
+ for(InterpreterShip ship : ships.values())
+ for(int j=0; j<10; j++)
+ ship._service();
+
+ // check the state of the ships
+ for(InterpreterShip ship : ships.values())
+ ship.shutdown();
- Log.println(Log.yellow(" DONE: ====== FLEET is halted. Have a nice day. ======"));
+ Log.println(Log.yellow(" DONE: ====== FLEET is halted. Have a nice day. ======"));
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
}
public void dispatch(Instruction i, long address) {
// Memory //////////////////////////////////////////////////////////////////////////////
- public int[] mem = new int[0];
-
public void dumpMem() {
Log.print(Log.cyan(" MEMORY: "));
for(int i=0; i<mem.length; i++) {
ship.addBenkoBox(name, this);
}
+ private static int default_addr;
+ private static int default_instr_addr;
+
public int bits;
- public int addr;
+ public int addr = (default_addr++);
public int instr_bits;
- public int instr_addr;
+ public int instr_addr = (default_instr_addr++);
protected boolean special = false;
protected boolean ihorn = false;
protected boolean dhorn = false;
public static PrintWriter log = new PrintWriter(new OutputStreamWriter(System.out));
public static void print(Object o) {
+ if (log==null) return;
try {
log.print(o);
} catch (Exception e) {
}
public static void println() { println(""); }
public static void println(Object o) {
+ if (log==null) return;
try {
log.println(o);
log.flush();
import edu.berkeley.fleet.api.Instruction;
import edu.berkeley.fleet.api.BenkoBox;
import edu.berkeley.fleet.*;
+import edu.berkeley.fleet.assembler.*;
import edu.berkeley.fleet.interpreter.*;
import edu.berkeley.fleet.slipway.*;
static boolean debugMemory = true;
static boolean dump_fabric = false;
static boolean dump_code = false;
+ static boolean test = false;
public static void main(String[] s) throws Exception {
for(int i=0; i<s.length; i++) {
dump_code = true;
continue;
+ } else if (s[i].startsWith("--test")) {
+ test = true;
+ continue;
+
} else if (s[i].startsWith("--memory=")) {
String val = s[i].substring(s[i].indexOf('=')+1);
if (val.equals("hide")) {
new Main().go();
}
+
public void go() throws Exception {
+ /*
+ if (test) {
+ test(new File("tests"));
+ System.exit(0);
+ }
+ */
+
Slipway fleet = new Slipway();
-
if (dump_fabric) {
fleet.dumpFabric(false);
} else {
dos.write(baos.toByteArray());
dos.close();
} else {
+ /*
if (debugMemory) { fleet.dumpMem(); }
fleet.go(baos.toByteArray());
if (debugMemory) { fleet.dumpMem(); }
+ */
}
}
}
import java.util.*;
import java.io.*;
import edu.berkeley.fleet.ships.*;
+/*
+
+debug alsoneeds port
+
+ DataInbox command = new DataInbox(this, "command", true);
+ DataOutbox ihorn = new DataOutbox(this, "ihorn", true, true, false);
+ DataOutbox dhorn = new DataOutbox(this, "dhorn", true, false, true);
+
+
+ */
public class Slipway extends Interpreter {