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.
*/
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) {
+ Ship timer = pool.allocateShip("Timer");
+ Ship debug = pool.allocateShip("Debug");
+ Dock debugIn = debug.getDock("in");
+
LoopFactory lf;
- fp.sendWord(memoryShip.getDock("inCBD").getDataDestination(),
- new BitVector(fleet.getWordWidth()).set( (run.baseAddress<<6) | run.instructions.length ));
- System.out.println("invoked.");
+
+ 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();
+ 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();
+
+ install(fp, 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) {
- 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.");
+ 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 makeCodeBag(Context ctx) {
- return makeCodeBag(ctx.emit());
+ public CodeBag getEndProgramCodeBag() {
+ if (end != null) return end;
+ end = new CodeBag(fleet, this);
+ return end;
}
- public CodeBag makeCodeBag(Instruction[] instructions) {
- int MAX_BAG_SIZE = (1<<7)-1;
- if (instructions.length > MAX_BAG_SIZE) {
- System.out.println("warning: code bag size is "+instructions.length+
- ", which exceeds maximum of "+MAX_BAG_SIZE+
- "; breaking into multiple bags");
- ArrayList<CodeBag> subBags = new ArrayList<CodeBag>();
- for(int block=0; block<instructions.length; block+=MAX_BAG_SIZE) {
- Instruction[] inst = new Instruction[Math.min(instructions.length-block, MAX_BAG_SIZE)];
- System.arraycopy(instructions, block, inst, 0, inst.length);
- subBags.add(makeCodeBag(inst));
- }
- throw new RuntimeException("FIXME: not done");
-
- } else {
- CodeBag codeBag = new CodeBag(this, instructions, leastUnallocatedAddress);
- System.out.println("instructions.length="+instructions.length);
+ /** 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)];
+ 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);
+ }
+
+ 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 = (1<<6)-1;
+
+ // 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 = new BitVector(fleet.getWordWidth());
+ descriptor.set( (leastUnallocatedAddress<<6) | instructions.length );
leastUnallocatedAddress += instructions.length;
- codeBags.add(codeBag);
- return codeBag;
+ 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