/*
- - refactor the cleanup into the subclasses of Port (phase1, phase2, etc)
- */
+ - refactor the cleanup into the subclasses of Port (phase1, phase2, etc)
+*/
// does peer.recvWord() have to honor the currently-set predicate?
public class Process {
+
public static int reset_count = 0;
public static HashSet<Dock> torpedoes = new HashSet<Dock>();
for(Module mod : modules)
mod.build(ctx);
}
- public void reset(Context ctx, int phase) {
+ public void reset(Context ctx, int phase, Destination ackDestination) {
reset_count = 0;
torpedoes.clear();
for(Module mod : modules)
- mod.reset(ctx, phase);
+ mod.reset(ctx, phase, ackDestination);
}
public class Module {
+ void doReset(Context ctx, int phase, Dock dock, Port peer, Destination ackDestination, boolean peerUsed) {
+ if (dock.getShip().getType().equals("Debug")) return;
+
+ switch(phase) {
+
+ // Phase 0: torpedo every output dock, put it in
+ // collecting mode. Cannot combine with phase 1,
+ // because until output docks are in vacuum mode we
+ // cannot be sure that the tokens to the input docks
+ // will eventually succeed. This may cause the
+ // instructions sent after the tokens to back up into
+ // the switch fabric.
+ case 0: {
+ if (!dock.isInputDock()) {
+ torpedoes.add(dock);
+ Context.LoopFactory lf = ctx.new LoopFactory(dock, 1);
+ lf.sendToken(ackDestination);
+ lf = lf.makeNext(0);
+ lf.abortLoopIfTorpedoPresent();
+ lf.collectWord();
+ reset_count++;
+ }
+ break;
+ }
+
+ // Phase 1: torpedo every input dock, put it in loopback mode
+ case 1: {
+ if (dock.isInputDock()) {
+ torpedoes.add(dock);
+ Context.LoopFactory lf = ctx.new LoopFactory(dock, 1);
+ lf.sendToken(ackDestination);
+
+ // FIXME: this won't work right for ports that
+ // get "shared" by two senders (for example,
+ // inAddrRead1/2)
+
+ if (peerUsed && peer!=null) {
+ lf = lf.makeNext(0);
+ lf.abortLoopIfTorpedoPresent();
+ ((OutPort)peer).recvWord(lf);
+ ((OutPort)peer).sendToken(lf);
+ }
+ reset_count++;
+ }
+ break;
+ }
+
+ // Phase 2: torpedo every output dock, have it absorb tokens
+ case 2: {
+ if (!dock.isInputDock()) {
+ torpedoes.add(dock);
+ Context.LoopFactory lf = ctx.new LoopFactory(dock, 1);
+ if (peer != null)
+ for(int i=0; i<((InPort)peer).getTokensToAbsorb(); i++)
+ lf.recvToken();
+ lf.sendToken(ackDestination);
+ reset_count++;
+ }
+ break;
+ }
+
+ // Phase 3: torpedo every input dock, and we're done
+ case 3: {
+ if (dock.isInputDock()) {
+ if (peerUsed && peer!=null) {
+ torpedoes.add(dock);
+ }
+ Context.LoopFactory lf = ctx.new LoopFactory(dock, 1);
+ lf.sendToken(ackDestination);
+ reset_count++;
+ }
+ break;
+ }
+
+
+ }
+ }
+
public Module() {
Process.this.modules.add(this);
}
public OutPort getOutPort(String name) { return (OutPort)ports.get(name); }
public void build(Context ctx) { for(Port p : ports.values()) p.build(ctx); }
- public void reset(Context ctx, int phase) { for(Port p : ports.values()) p.reset(ctx, phase); }
+ public void reset(Context ctx, int phase, Destination ackDestination) {
+ for(Port p : ports.values()) p.reset(ctx, phase, ackDestination);
+ }
public abstract class Port {
public final String name;
Module.this.ports.put(name,this);
}
public abstract void build(Context ctx);
- public abstract void reset(Context ctx, int phase);
+ public abstract void reset(Context ctx, int phase, Destination ackDestination);
}
public abstract class InPort extends Port {
for(int i=0; i<pattern.length; i++) if (pattern[i]==null) return true;
return false;
}
- public void reset(Context ctx, int phase) {
- if (dock.getShip().getType().equals("Debug")) {
- return;
- }
- switch(phase) {
- case 0: {
- torpedoes.add(dock);
- break;
- }
- case 2: {
- reset_count++;
- Context.LoopFactory lf = ctx.new LoopFactory(dock, 1);
- lf.sendToken(fleet.getShip("Debug",0).getDock("in").getDataDestination());
- if (peerUsed()) {
- lf = lf.makeNext(0);
- lf.abortLoopIfTorpedoPresent();
- peer.recvWord(lf);
- peer.sendToken(lf);
- }
- break;
- }
- case 3: {
- if (peerUsed()) {
- torpedoes.add(dock);
- }
- break;
- }
- }
+ public void reset(Context ctx, int phase, Destination ackDestination) {
+ doReset(ctx, phase, dock, peer, ackDestination, peerUsed());
}
protected void build(Context ctx, Context.LoopFactory lf) {
int inflight = (count != 0 && count < getInflight()) ? count : getInflight();
lf.collectWord();
peer.sendWord(lf);
}
- public void reset(Context ctx, int phase) {
-
- // set this to true to get a more "fine grained" report of the shutdown process
- boolean extratokens = false;
-
- switch(phase) {
- case 0: {
- torpedoes.add(dock);
- break;
- }
- case 1: {
- Context.LoopFactory lf = ctx.new LoopFactory(dock, 1);
- if (peer != null) {
- for(int i=0; i<peer.getTokensToAbsorb(); i++) {
- lf.recvToken();
- if (extratokens) lf.sendToken(fleet.getShip("Debug",0).getDock("in").getDataDestination());
- }
- }
- lf.sendToken(fleet.getShip("Debug",0).getDock("in").getDataDestination());
- lf = lf.makeNext(0);
- lf.abortLoopIfTorpedoPresent();
- lf.collectWord();
- break;
- }
- case 2: {
- reset_count++;
- if (extratokens && peer != null) reset_count += peer.getTokensToAbsorb();
- break;
- }
- case 3: {
- torpedoes.add(dock);
- break;
- }
- }
+ public void reset(Context ctx, int phase, Destination ackDestination) {
+ doReset(ctx, phase, dock, peer, ackDestination, true);
}
}
}
}
/**
- * For every datum transmitted to in, pass it along to out and
- * deliver the constant at out. Flow control in<->out is
+ * Deliver the constant at out forever. Flow control in<->out is
* maintained, but out is not flow-controlled, so be sure
* that every datum sent there is consumed synchronously wiht
* data items sent to out.
public void sendToken(Context.LoopFactory lf) { }
public void recvWord(Context.LoopFactory lf) { }
public void build(Context ctx) { }
- public void reset(Context ctx, int phase) { }
+ public void reset(Context ctx, int phase, Destination ackDestination) { }
public void setPeer(InPort peer) {
this.peer = peer;
DockInPort pip = ((DockInPort)peer);
public void sendToken(Context.LoopFactory lf) { }
public void recvWord(Context.LoopFactory lf) { }
public void build(Context ctx) { }
- public void reset(Context ctx, int phase) { }
+ public void reset(Context ctx, int phase, Destination ackDestination) { }
public void setPeer(InPort peer) {
this.peer = peer;
DockInPort pip = ((DockInPort)peer);
public void sendWord(Context.LoopFactory lf) { lf.sendWord(ship.getDock("inAddrRead").getDataDestination(), new BitVector(1).set(0)); }
public void build(Context ctx) { }
public int getTokensToAbsorb() { return outRead1.peer.getTokensToAbsorb(); }
- public void reset(Context ctx, int phase) {
- switch(phase) {
- case 0:
- torpedoes.add(ship.getDock("inAddrRead"));
- break;
- case 2:
- reset_count++;
- Context.LoopFactory lf = ctx.new LoopFactory(ship.getDock("inAddrRead"), 1);
- lf.sendToken(fleet.getShip("Debug",0).getDock("in").getDataDestination());
- break;
- }
+ public void reset(Context ctx, int phase, Destination ackDestination) {
+ doReset(ctx, phase, ship.getDock("inAddrRead"), null, ackDestination, false);
}
};
this.inAddrRead2 = new InPort("inAddrRead2") {
public void sendWord(Context.LoopFactory lf) { lf.sendWord(ship.getDock("inAddrRead").getDataDestination(), new BitVector(1).set(1)); }
public void build(Context ctx) { }
public int getTokensToAbsorb() { return outRead2.peer.getTokensToAbsorb(); }
- public void reset(Context ctx, int phase) { }
+ public void reset(Context ctx, int phase, Destination ackDestination) { }
};
this.outRead1 = new OutPort("outRead1") {
public void sendToken(Context.LoopFactory lf) { inAddrRead1.peer.sendToken(lf); }
public void recvWord(Context.LoopFactory lf) { lf.recvWord(); }
public void build(Context ctx) { }
- public void reset(Context ctx, int phase) { }
+ public void reset(Context ctx, int phase, Destination ackDestination) { }
};
this.outRead2 = new OutPort("outRead2") {
public void sendToken(Context.LoopFactory lf) { inAddrRead2.peer.sendToken(lf); }
public void recvWord(Context.LoopFactory lf) { lf.recvWord(); }
public void build(Context ctx) { }
- public void reset(Context ctx, int phase) { }
+ public void reset(Context ctx, int phase, Destination ackDestination) { }
};
this.outWrite = new DockOutPort("out", ship.getDock("out")) {
protected void build(Context ctx, Context.LoopFactory lf) {
public static void main(String[] s) throws Exception {
Fleet fleet = new Fpga();
+ //Fleet fleet = new Interpreter(false);
+
Random random = new Random(System.currentTimeMillis());
long[] vals = new long[256];
for(int i=0; i<vals.length; i++) {
Ship mem1 = fleet.getShip("Memory", 0);
Ship mem2 = fleet.getShip("Memory", 1);
+ //Ship mem2 = fleet.getShip("DDR2", 0);
FleetProcess fp;
int stride = 1;
System.out.println(bvs[i].toLong());
}
+ // FIXME: check for "lingering" torpedoes?
public static void verifyClean(FleetProcess fp) {
Ship debug = fp.getFleet().getShip("Debug", 0);
Dock debugIn = debug.getDock("in");
lf.deliver();
lf.literal(5);
lf.deliver();
- ArrayList<Instruction> ai = new ArrayList<Instruction>();
- ctx.emit(ai);
- for(Instruction ins : ai) fp.sendInstruction(ins);
+ Gadgets.dispatch(fp, ctx);
fp.flush();
System.out.println("checking debug.in");
lf.sendToken(dock.getDataDestination(), new BitVector(1).set(reverse ? 1 : 0));
lf.sendToken(dock.getDataDestination(), new BitVector(1).set(reverse ? 0 : 1));
lf = lf.makeNext(2);
+
+ // if a torpedo was lying in wait, the problem will be manifest as a "freezup"
+ lf.abortLoopIfTorpedoPresent();
+
lf.recvToken();
lf.setFlags(FlagFunction.ZERO.add(FlagC), FlagFunction.ZERO);
lf.setPredicate(Predicate.NotFlagA);
lf.sendToken(debugIn.getDataDestination(), new BitVector(1).set(1));
lf.setPredicate(null);
- ai = new ArrayList<Instruction>();
- ctx.emit(ai);
- for(Instruction ins : ai) fp.sendInstruction(ins);
+ Gadgets.dispatch(fp, ctx);
fp.flush();
long kk;
}
}
- // FIXME: numbers seem to get duplicated when stride=2
public static long[] mergeSort(FleetProcess fp, Fleet fleet,
long[] vals, int vals_length, int stride_length,
Ship memoryShip1, Ship memoryShip2) throws Exception {
// So far: we have four spare Counter ships; one can be used for resetting
for(int i=0; i<2; i++) {
- RepeatModule r1 = proc.new RepeatModule();
DownCounterModule c0 = proc.new DownCounterModule();
DownCounterModule c1 = proc.new DownCounterModule();
- AluModule alu = proc.new AluModule();
c0.start.connect(proc.new ForeverModule(stride_length).out);
c0.incr.connect(proc.new ForeverModule(1).out);
c1.start.connect(proc.new OnceModule(end_of_data + i*stride_length).out);
c1.incr.connect(proc.new OnceModule(stride_length*2).out);
+ RepeatModule r1 = proc.new RepeatModule();
r1.val.connect(c1.out);
r1.count.connect(proc.new ForeverModule(stride_length).out);
+ AluModule alu = proc.new AluModule();
alu.in1.connect(r1.out);
alu.in2.connect(c0.out);
- alu.inOp.connect(proc.new ForeverModule(2 /* ADD */).out);
+ alu.inOp.connect(proc.new ForeverModule(2).out); // ADD
alu.out.connect(i==0 ? mm.inAddrRead1 : mm.inAddrRead2);
PunctuatorModule punc = proc.new PunctuatorModule(-1);
punc.out.connect(i==0 ? sm.in1 : sm.in2);
}
-
UnPunctuatorModule unpunc = proc.new UnPunctuatorModule();
unpunc.val.connect(sm.out);
unpunc.count.connect(proc.new ForeverModule(2*stride_length).out);
mm2.inAddrWrite.connect(cw.out);
mm2.inDataWrite.connect(unpunc.out);
mm2.outWrite.connect(dm.in);
-
+
//////////////////////////////////////////////////////////////////////////////
Context ctx = new Context(fp.getFleet());
for(int i=0; i<vals_length; i++) {
System.out.print("\rreading back... " + i+"/"+vals_length+" ");
- System.out.print(" (prev result: " + fp.recvWord() + ")");
+ BitVector rec = fp.recvWord();
+ System.out.print(" (prev result: " + rec + " = " + rec.toLong() + ")");
}
System.out.println("\rdone. ");
Dock debugIn = fleet.getShip("Debug",0).getDock("in");
Dock fred = debugIn;
fp.sendToken(debugIn.getInstructionDestination());
+ fp.flush();
Context.LoopFactory lf = ctx2.new LoopFactory(debugIn, 0);
lf.literal(0);
lf.recvToken();
lf.deliver();
- ctx2.emit(ai = new ArrayList<Instruction>());
- for(Instruction ins : ai)
- fp.sendInstruction(ins);
+ Gadgets.dispatch(fp, ctx2);
fp.flush();
int count = 0;
+ Ship counter = proc.pool.allocateShip("Counter");
+
for(int phase=0; phase<=3; phase++) {
System.out.println("== phase "+phase+" ==================================================================");
ctx2 = new Context(fp.getFleet());
- proc.reset(ctx2, phase);
-
- final Semaphore sem = new Semaphore(0);
- final FleetProcess fpf = fp;
- final int phasef = phase;
- new Thread() {
- public void run() {
- for(int ii=0; ii<reset_count; ii++) {
- System.out.print("\r phase "+phasef+" ==> " + (ii+1) + " / " + reset_count);
- fpf.recvWord();
- }
- sem.release();
- }}.start();
+
+ Destination ackDestination = counter.getDock("in2").getDataDestination();
+ proc.reset(ctx2, phase, ackDestination);
+
+ Context ctx3 = new Context(fp.getFleet());
+ lf = ctx3.new LoopFactory(counter.getDock("inOp"), 1);
+ lf.literal(9);
+ lf.deliver();
+ lf.literal(5);
+ lf.deliver();
+ lf = ctx3.new LoopFactory(counter.getDock("in1"), 1);
+ lf.literal(reset_count-1);
+ lf.deliver();
+ lf.literal(1);
+ lf.deliver();
+ lf = ctx3.new LoopFactory(counter.getDock("in2"), 0);
+ lf.abortLoopIfTorpedoPresent();
+ lf.recvWord();
+ lf.deliver();
+ lf = ctx3.new LoopFactory(counter.getDock("out"), 1);
+ lf.collectWord();
+ lf.sendToken(counter.getDock("in2").getInstructionDestination()); // HACK: we don't check to make sure this hits
+ lf.sendToken(debugIn.getDataDestination());
+ Gadgets.dispatch(fp, ctx3); // HACK: we don't check to make sure that this is "firmly in place"
for(Dock dock : torpedoes) fp.sendToken(dock.getInstructionDestination());
- ctx2.emit(ai = new ArrayList<Instruction>());
- for(Instruction ins : ai) fp.sendInstruction(ins);
+ Gadgets.dispatch(fp, ctx2);
fp.flush();
-
- sem.acquire();
System.out.println("flushed");
+ fp.recvWord();
+ System.out.println("phase done");
+
System.out.println();
}
fp.sendToken(debugIn.getInstructionDestination());
fp.flush();
- System.out.println("verifying cleanup:");
+ //System.out.println("verifying cleanup:");
//verifyClean(fp);
+ System.out.println("reading back:");
long[] ret = null;
if (vals != null) {
ret = new long[vals_length];