import edu.berkeley.fleet.api.*;
import java.util.*;
import java.net.*;
+import java.io.*;
/**
* A program is a collection of CodeBags resident in a particular Memory.
+ *
+ * FIXME: should every Program have an associated ShipPool?
*/
public class Program {
- private Ship memoryShip;
- private Fleet fleet;
+ public final Fleet fleet;
+ public final Ship memoryShip;
+
+ private CodeBag end = null;
+
private long leastUnallocatedAddress;
private long startAddress;
- private HashSet<CodeBag> codeBags = new HashSet<CodeBag>();
+ private ArrayList<CodeBag> codeBags = new ArrayList<CodeBag>();
+ private ArrayList<Instruction> all_instructions = new ArrayList<Instruction>();
public Program(Ship memoryShip) { this(memoryShip, 0); }
public Program(Ship memoryShip, long startAddress) {
this.leastUnallocatedAddress = startAddress;
}
- public void run(FleetProcess fp, CodeBag run) {
- System.out.println("invoking...");
- Context ctx = new Context(fleet);
+ public Destination getCBDDestination() {
+ return memoryShip.getDock("inCBD").getDataDestination();
+ }
+
+ public long run(FleetProcess fp, CodeBag run, ShipPool pool_) {
+ ShipPool pool = new ShipPool(pool_);
+ Ship timer = pool.allocateShip("Timer");
+ Ship debug = pool.allocateShip("Debug");
+ Dock debugIn = debug.getDock("in");
+
LoopFactory lf;
- lf = new LoopFactory(ctx, memoryShip.getDock("inCBD"), 1);
- lf.literal( (run.baseAddress<<6) | run.instructions.length );
+
+ CodeBag start = new CodeBag(fleet, this);
+ lf = start.loopFactory(timer.getDock("out"), 1);
+ lf.collectWord();
+ lf.sendWord(debugIn.getDataDestination());
+ lf = start.loopFactory(debugIn, 1);
+ lf.recvWord();
lf.deliver();
- ctx.dispatch(fp);
- System.out.println("invoked.");
+ lf.recvWord();
+ lf.deliver();
+ start.sendWord(run.getDescriptor(), getCBDDestination());
+
+ CodeBag done = end;
+ lf = done.loopFactory(timer.getDock("out"), 1);
+ lf.collectWord();
+ lf.sendWord(debugIn.getDataDestination());
+
+ start.seal();
+ done.seal();
+
+ pool.setParent(null);
+ install(fp, pool_);
+ pool.setParent(pool_);
+
+ MemoryUtils.putMemoryShipInDispatchMode(fp, memoryShip);
+ fp.sendWord(getCBDDestination(), start.getDescriptor().getBitVector());
+ fp.flush();
+ long now = System.currentTimeMillis();
+ System.out.println("waiting for timestamps to come back...");
+ BitVector bv1 = fp.recvWord();
+ System.out.println();
+ System.out.println("got start time (bv="+bv1+" = "+bv1.toLong()+")");
+ BitVector bv2 = fp.recvWord();
+ System.out.println("got end time (bv="+bv2+" = "+bv2.toLong()+")");
+ long ret = (bv2.toLong()-bv1.toLong());
+ long simtime = (System.currentTimeMillis()-now)/1000;
+ System.out.println("total run time = " + ret + " gate delays, " + (ret/40) + "ns (simulation time="+simtime+"sec)");
+ MemoryUtils.removeMemoryShipFromDispatchMode(fp, memoryShip);
+
+ return ret;
}
- public void install(FleetProcess fp) {
+ public void dump(String file) {
+ try {
+ FileOutputStream fos = new FileOutputStream(file);
+ PrintWriter pw = new PrintWriter(new OutputStreamWriter(fos));
+ for(int i=0; i<codeBags.size(); i++)
+ for(Instruction in : codeBags.get(i).emit())
+ pw.println(in);
+ pw.flush();
+ pw.close();
+ } catch (Exception e) { throw new RuntimeException(e); }
+ }
+
+ public CodeBag getEndProgramCodeBag() {
+ if (end != null) return end;
+ end = new CodeBag(fleet, this);
+ return end;
+ }
+
+ /** the provided pool should be a sibling of the one which holds this Program's instructions */
+ public void install(FleetProcess fp, ShipPool pool) {
+ for(int i=0; i<codeBags.size(); i++)
+ codeBags.get(i).emit();
BitVector[] bvs = new BitVector[(int)(leastUnallocatedAddress-startAddress)];
- int j = 0;
- for(CodeBag cb : codeBags)
- for(int i=0; i<cb.instructions.length; i++)
- bvs[j++] = fleet.encodeInstruction(cb.instructions[i], memoryShip.getDock("out"));
- System.out.println("writing... ("+bvs.length+" words)");
- MemoryUtils.writeMem(fp, memoryShip, startAddress, bvs);
- System.out.println("written.");
+ for(int i=0; i<bvs.length; i++) {
+ bvs[i] = fleet.encodeInstruction(all_instructions.get(i), memoryShip.getDock("out"));
+ }
+ MemoryUtils.writeMem(fp, pool, memoryShip, startAddress, bvs);
}
- public CodeBag makeCodeBag(Context ctx) {
- Instruction[] instructions = ctx.emit();
- CodeBag codeBag = new CodeBag(this, instructions, leastUnallocatedAddress);
- System.out.println("instructions.length="+instructions.length);
- leastUnallocatedAddress += instructions.length;
- codeBags.add(codeBag);
- return codeBag;
+ BitVector addInstructions(Instruction[] instructions) {
+
+ // CodeBags are "daisy chained" to eliminate any possibility
+ // of cloggage at the inCBD port as a result of more CBD's
+ // being dispatched than the maximum number that fit in the
+ // data fifo at that dock.
+
+ int MAX_BAG_SIZE = fleet.getMaxCodeBagSize();
+
+ // FUZZ is an estimate of the number of instructions required
+ // to dispatch a code bag descriptor
+ int FUZZ = 4;
+
+ if (instructions.length <= MAX_BAG_SIZE) {
+ BitVector descriptor = fleet.makeCodeBagDescriptor(leastUnallocatedAddress, instructions.length);
+ leastUnallocatedAddress += instructions.length;
+ for(Instruction i : instructions)
+ all_instructions.add(i);
+ return descriptor;
+ }
+
+ System.out.println("warning: code bag size is "+instructions.length+
+ ", which exceeds maximum of "+MAX_BAG_SIZE+
+ "; breaking into multiple bags");
+
+ Instruction[] rest = new Instruction[instructions.length - (MAX_BAG_SIZE-FUZZ)];
+ System.arraycopy(instructions, MAX_BAG_SIZE-FUZZ, rest, 0, rest.length);
+
+ DeferredBitVector restbag = addInstructions(rest);
+ CodeBag ctx = new CodeBag(fleet);
+ ctx.sendWord(restbag, getCBDDestination());
+ Instruction[] fuzz = ctx.emit();
+ if (fuzz.length > FUZZ) throw new RuntimeException("FUZZ="+FUZZ+", fuzz.length="+fuzz.length);
+ Instruction[] self = new Instruction[fuzz.length+MAX_BAG_SIZE-FUZZ];
+ System.arraycopy(instructions, 0, self, 0, MAX_BAG_SIZE-FUZZ);
+ System.arraycopy(fuzz, 0, self, MAX_BAG_SIZE-FUZZ, fuzz.length);
+ return addInstructions(self);
}
}
\ No newline at end of file