1 package edu.berkeley.fleet.loops;
2 import edu.berkeley.fleet.api.*;
8 * A program is a collection of CodeBags resident in a particular Memory.
10 * FIXME: should every Program have an associated ShipPool?
12 public class Program {
14 public final Fleet fleet;
15 public final Ship memoryShip;
17 private CodeBag end = null;
19 private long leastUnallocatedAddress;
20 private long startAddress;
22 private ArrayList<CodeBag> codeBags = new ArrayList<CodeBag>();
23 private ArrayList<Instruction> all_instructions = new ArrayList<Instruction>();
25 public Program(Ship memoryShip) { this(memoryShip, 0); }
26 public Program(Ship memoryShip, long startAddress) {
27 this.fleet = memoryShip.getFleet();
28 this.memoryShip = memoryShip;
29 this.startAddress = startAddress;
30 this.leastUnallocatedAddress = startAddress;
33 public Destination getCBDDestination() {
34 return memoryShip.getDock("inCBD").getDataDestination();
37 public long run(FleetProcess fp, CodeBag run, ShipPool pool_) {
38 ShipPool pool = new ShipPool(pool_);
39 Ship timer = pool.allocateShip("Timer");
40 Ship debug = pool.allocateShip("Debug");
41 Dock debugIn = debug.getDock("in");
45 CodeBag start = new CodeBag(fleet, this);
46 lf = start.loopFactory(timer.getDock("out"), 1);
47 // collect twice just to be safe
50 lf.sendWord(debugIn.getDataDestination());
52 lf = start.loopFactory(debugIn, 1);
57 start.sendWord(run.getDescriptor(), getCBDDestination());
60 lf = done.loopFactory(timer.getDock("out"), 1);
61 // collect twice just to be safe
64 lf.sendWord(debugIn.getDataDestination());
71 pool.setParent(pool_);
73 MemoryUtils.putMemoryShipInDispatchMode(fp, memoryShip);
74 fp.sendWord(getCBDDestination(), start.getDescriptor().getBitVector());
76 long now = System.currentTimeMillis();
77 System.out.println("waiting for timestamps to come back...");
78 BitVector bv1 = fp.recvWord();
80 System.out.println("got start time (bv="+bv1+" = "+bv1.toLong()+")");
81 BitVector bv2 = fp.recvWord();
82 System.out.println("got end time (bv="+bv2+" = "+bv2.toLong()+")");
83 long ret = (bv2.toLong()-bv1.toLong());
84 long simtime = (System.currentTimeMillis()-now)/1000;
85 System.out.println("total run time = " + ret + " gate delays, " + (ret/40) + "ns (simulation time="+simtime+"sec)");
86 MemoryUtils.removeMemoryShipFromDispatchMode(fp, memoryShip);
91 public void dump(String file) {
93 FileOutputStream fos = new FileOutputStream(file);
94 PrintWriter pw = new PrintWriter(new OutputStreamWriter(fos));
95 for(int i=0; i<codeBags.size(); i++)
96 for(Instruction in : codeBags.get(i).emit())
100 } catch (Exception e) { throw new RuntimeException(e); }
103 public CodeBag getEndProgramCodeBag() {
104 if (end != null) return end;
105 end = new CodeBag(fleet, this);
109 /** the provided pool should be a sibling of the one which holds this Program's instructions */
110 public void install(FleetProcess fp, ShipPool pool) {
111 for(int i=0; i<codeBags.size(); i++)
112 codeBags.get(i).emit();
113 BitVector[] bvs = new BitVector[(int)(leastUnallocatedAddress-startAddress)];
114 for(int i=0; i<bvs.length; i++) {
115 bvs[i] = fleet.encodeInstruction(all_instructions.get(i), memoryShip.getDock("out"));
117 MemoryUtils.writeMem(fp, pool, memoryShip, startAddress, bvs);
120 BitVector addInstructions(Instruction[] instructions) {
122 // CodeBags are "daisy chained" to eliminate any possibility
123 // of cloggage at the inCBD port as a result of more CBD's
124 // being dispatched than the maximum number that fit in the
125 // data fifo at that dock.
127 int MAX_BAG_SIZE = fleet.getMaxCodeBagSize();
129 // FUZZ is an estimate of the number of instructions required
130 // to dispatch a code bag descriptor
133 if (instructions.length <= MAX_BAG_SIZE) {
134 BitVector descriptor = fleet.makeCodeBagDescriptor(leastUnallocatedAddress, instructions.length);
135 leastUnallocatedAddress += instructions.length;
136 for(Instruction i : instructions)
137 all_instructions.add(i);
141 System.out.println("warning: code bag size is "+instructions.length+
142 ", which exceeds maximum of "+MAX_BAG_SIZE+
143 "; breaking into multiple bags");
145 Instruction[] rest = new Instruction[instructions.length - (MAX_BAG_SIZE-FUZZ)];
146 System.arraycopy(instructions, MAX_BAG_SIZE-FUZZ, rest, 0, rest.length);
148 DeferredBitVector restbag = addInstructions(rest);
149 CodeBag ctx = new CodeBag(fleet);
150 ctx.sendWord(restbag, getCBDDestination());
151 Instruction[] fuzz = ctx.emit();
152 if (fuzz.length > FUZZ) throw new RuntimeException("FUZZ="+FUZZ+", fuzz.length="+fuzz.length);
153 Instruction[] self = new Instruction[fuzz.length+MAX_BAG_SIZE-FUZZ];
154 System.arraycopy(instructions, 0, self, 0, MAX_BAG_SIZE-FUZZ);
155 System.arraycopy(fuzz, 0, self, MAX_BAG_SIZE-FUZZ, fuzz.length);
156 return addInstructions(self);