--- /dev/null
+package edu.berkeley.fleet.ir;
+import java.util.*;
+import java.net.*;
+import edu.berkeley.fleet.two.*;
+import edu.berkeley.fleet.api.*;
+import edu.berkeley.fleet.fpga.*;
+import edu.berkeley.fleet.api.Instruction.*;
+import edu.berkeley.fleet.api.Instruction.Set;
+import edu.berkeley.fleet.api.Instruction.Set.*;
+import static edu.berkeley.fleet.api.Predicate.*;
+import static edu.berkeley.fleet.util.BitManipulations.*;
+
+
+/*
+ - refactor the cleanup into the subclasses of Port (phase1, phase2, etc)
+ */
+
+// does peer.recvWord() have to honor the currently-set predicate?
+
+// public class ReplaceModule extends Module { }
+// public class CountMergeModule extends Module { }
+// public class SortMergeModule extends Module { }
+// public class FanOutModule extends Module { }
+// public class MemoryModule extends Module { }
+// public class DoneModule extends Module { }
+
+public class Process {
+
+ public static int reset_count = 0;
+ public static HashSet<Dock> torpedoes = new HashSet<Dock>();
+
+ public final Fleet fleet;
+ public final ShipPool pool;
+
+ public Process(Fleet fleet) {
+ this.fleet = fleet;
+ this.pool = new ShipPool(fleet);
+ }
+
+ private HashSet<Module> modules = new HashSet<Module>();
+
+ public void build(Context ctx) {
+ for(Module mod : modules)
+ mod.build(ctx);
+ }
+ public void reset(Context ctx, int phase) {
+ reset_count = 0;
+ torpedoes.clear();
+ for(Module mod : modules)
+ mod.reset(ctx, phase);
+ }
+
+ public class Module {
+
+ public Module() {
+ Process.this.modules.add(this);
+ }
+
+ private HashMap<String,Port> ports = new HashMap<String,Port>();
+
+ public InPort getInPort(String name) { return (InPort)ports.get(name); }
+ 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 abstract class Port {
+ public final String name;
+ public Port(String name) {
+ this.name = name;
+ if (Module.this.ports.get(name)!=null) throw new RuntimeException();
+ Module.this.ports.put(name,this);
+ }
+ public abstract void build(Context ctx);
+ public abstract void reset(Context ctx, int phase);
+ }
+
+ public abstract class InPort extends Port {
+ OutPort peer;
+ public InPort(String name) { super(name); }
+ public void connect(OutPort peer) {
+ this.setPeer(peer);
+ peer.setPeer(this);
+ }
+ public void setPeer(OutPort peer) {
+ if (this.peer!=null) throw new RuntimeException("cannot call setPeer() twice");
+ this.peer = peer;
+ }
+
+ /** this port's peer (an OutPort) invokes this to have "recvToken" or equivalent inserted */
+ public abstract void recvToken(Context.LoopFactory loopfactory_at_output_dock);
+ /** this port's peer (an OutPort) invokes this to have "sendWord" or equivalent inserted */
+ public abstract void sendWord(Context.LoopFactory loopfactory_at_output_dock);
+ }
+
+ public abstract class OutPort extends Port {
+ InPort peer;
+ public OutPort(String name) { super(name); }
+ public void connect(InPort peer) {
+ this.setPeer(peer);
+ peer.setPeer(this);
+ }
+ public void setPeer(InPort peer) {
+ if (this.peer!=null) throw new RuntimeException("cannot call setPeer() twice");
+ this.peer = peer;
+ }
+
+ /** this port's peer (an InPort) invokes this to have "sendToken" or equivalent inserted */
+ public abstract void sendToken(Context.LoopFactory loopfactory_at_input_dock);
+ /** this port's peer (an InPort) invokes this to have "recvWord" or equivalent inserted */
+ public abstract void recvWord(Context.LoopFactory loopfactory_at_input_dock);
+ }
+
+ public final class DockInPort extends InPort {
+ final Dock dock;
+ int count;
+ BitVector[] pattern;
+ public DockInPort(String name, Dock dock) { this(name, dock, 0); }
+ public DockInPort(String name, Dock dock, int count) { this(name, dock, count, new BitVector[] { null }); }
+ public DockInPort(String name, Dock dock, int count, BitVector[] pattern) {
+ super(name);
+ this.dock = dock;
+ this.count = count;
+ this.pattern = pattern;
+ }
+ public void recvToken(Context.LoopFactory lf) { lf.recvToken(); }
+ public void sendWord(Context.LoopFactory lf) { lf.sendWord(dock.getDataDestination()); }
+ public void build(Context ctx) { build(ctx, ctx.new LoopFactory(dock, 1)); }
+ // number-in-flight is considered a property of the input dock in a pair
+ //public int getInflight() { return 4; }
+ public int getInflight() { return 1; }
+ public void reset(Context ctx, int phase) {
+ if (dock.getShip().getType().equals("Debug")) {
+ return;
+ }
+ switch(phase) {
+ case 0: {
+ torpedoes.add(dock);
+ break;
+ }
+ case 1: {
+ // FIXME
+ reset_count++;
+ Context.LoopFactory lf = ctx.new LoopFactory(dock, 1);
+ lf.sendToken(fleet.getShip("Debug",0).getDock("in").getDataDestination());
+ if (peer != null && peer instanceof DockOutPort) {
+ DockOutPort dop_peer = (DockOutPort)peer;
+ lf = lf.makeNext(0);
+ lf.abortLoopIfTorpedoPresent();
+ lf.recvToken();
+ lf.sendToken(dop_peer.dock.getDataDestination());
+ }
+ break;
+ }
+ case 2: {
+ if (peer != null && peer instanceof DockOutPort) {
+ torpedoes.add(dock);
+ }
+ break;
+ }
+ }
+ }
+ protected void build(Context ctx, Context.LoopFactory lf) {
+ int inflight = (count != 0 && count < getInflight()) ? count : getInflight();
+
+ if (peer!=null)
+ for(int i=0; i<inflight; i++) peer.sendToken(lf);
+
+ lf = lf.makeNext(count);
+ for(int i=0; i<pattern.length; i++) {
+ if (pattern[i]==null) {
+ lf.abortLoopIfTorpedoPresent();
+ peer.recvWord(lf);
+ lf.deliver();
+ peer.sendToken(lf);
+ } else {
+ lf.literal(pattern[i]);
+ lf.abortLoopIfTorpedoPresent();
+ lf.deliver();
+ }
+ }
+
+ if (count!=0) {
+ // "torpedoable nop" to keep the dock in a receptive state
+ lf.abortLoopIfTorpedoPresent();
+ lf.recvToken();
+ }
+ }
+ }
+
+ public final class DockOutPort extends OutPort {
+ public final Dock dock;
+ public final int count;
+ public DockOutPort(String name, Dock dock) { this(name, dock, 0); }
+ public DockOutPort(String name, Dock dock, int count) { super(name); this.dock = dock; this.count = count; }
+ public void sendToken(Context.LoopFactory lf) { lf.sendToken(dock.getDataDestination()); }
+ public void recvWord(Context.LoopFactory lf) { lf.recvWord(); }
+ public void build(Context ctx) { build(ctx, ctx.new LoopFactory(dock, 1)); }
+ protected void build(Context ctx, Context.LoopFactory lf) {
+ if (peer==null) return;
+ // FIXME: no setup?
+ lf = lf.makeNext(count);
+ lf.abortLoopIfTorpedoPresent();
+ peer.recvToken(lf);
+ //lf.abortLoopIfTorpedoPresent(); // FIXME: do I need this twice?
+ lf.collectWord();
+ peer.sendWord(lf);
+ // FIXME: cleanup
+ }
+ public void reset(Context ctx, int phase) {
+ switch(phase) {
+ case 0: {
+ torpedoes.add(dock);
+ break;
+ }
+ case 1: {
+ reset_count++;
+ Context.LoopFactory lf = ctx.new LoopFactory(dock, 1);
+ if (peer instanceof DockInPort) {
+ DockInPort dip_peer = (DockInPort)peer;
+ for(int i=0; i<dip_peer.getInflight(); i++) {
+ lf.recvToken();
+ }
+ //lf.sendToken(dip_peer.dock.getInstructionDestination());
+ }
+ lf.sendToken(fleet.getShip("Debug",0).getDock("in").getDataDestination());
+ lf = lf.makeNext(0);
+ lf.abortLoopIfTorpedoPresent();
+ lf.collectWord();
+ break;
+ }
+ case 2: {
+ torpedoes.add(dock);
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ private BitVector bv(long l) { return new BitVector(fleet.getWordWidth()).set(l); }
+
+ /**
+ * For every datum transmitted to in, pass it along to out and
+ * deliver the constant at out. 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 class ForeverModule extends Module {
+ private BitVector bv;
+ public final OutPort out = new OutPort("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 setPeer(InPort peer) {
+ this.peer = peer;
+ DockInPort pip = ((DockInPort)peer);
+ for(int i=0; i<pip.pattern.length; i++) {
+ if (pip.pattern[i]==null)
+ pip.pattern[i] = bv;
+ }
+ }
+ };
+ public ForeverModule(long l) { this(new BitVector(fleet.getWordWidth()).set(l)); }
+ public ForeverModule(final BitVector bv) { this.bv = bv; }
+ }
+
+ public class OnceModule extends Module {
+ private BitVector bv;
+ public final OutPort out = new OutPort("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 setPeer(InPort peer) {
+ this.peer = peer;
+ DockInPort pip = ((DockInPort)peer);
+ BitVector[] pip_pattern = pip.pattern;
+ BitVector[] temp = new BitVector[pip_pattern.length * 2];
+ int j = 0;
+ int i = 0;
+ boolean done = false;
+ // FIXME: if peer.count is already 1, this gets simpler and different
+ for(i=0; i<temp.length; i++) {
+ if (pip_pattern[j] != null) {
+ temp[i] = pip_pattern[j];
+ } else {
+ if (done) break;
+ done = true;
+ temp[i] = bv;
+ }
+ j++;
+ if (j >= pip_pattern.length) j = 0;
+ }
+ pip.pattern = new BitVector[i];
+ System.arraycopy(temp, 0, pip.pattern, 0, i);
+ pip.count = 1;
+ }
+ };
+ public OnceModule(long l) { this(new BitVector(fleet.getWordWidth()).set(l)); }
+ public OnceModule(final BitVector bv) { this.bv = bv; }
+ }
+
+ public class DebugModule extends Module {
+ public final Ship ship = pool.allocateShip("Debug");
+ public final InPort in = new DockInPort("in", ship.getDock("in"));
+ // NOTE: shutdown needs to treat this specially
+ public DebugModule() { }
+ }
+
+ public class UnPunctuatorModule extends Module {
+ private final Ship ship = pool.allocateShip("Counter");
+ public final OutPort out = new DockOutPort("out", ship.getDock("out"));
+ public final InPort val = new DockInPort("in1", ship.getDock("in1"));
+ public final InPort count = new DockInPort("in2", ship.getDock("in2"), 0, new BitVector[] { null, bv(1) });
+ public final InPort op = new DockInPort("inOp", ship.getDock("inOp"), 0, new BitVector[] { bv(6 /*PASS_C2_V1*/), bv(10 /*DROP_C2_V1*/) } );
+ public UnPunctuatorModule() { }
+ }
+
+ public class PunctuatorModule extends Module {
+ private final long punc;
+ private final Ship ship = pool.allocateShip("Counter");
+ public final OutPort out = new DockOutPort("out", ship.getDock("out"));
+ public final InPort val = new DockInPort("in1", ship.getDock("in1"));
+ public final InPort op = new DockInPort("inOp", ship.getDock("inOp"), 0, new BitVector[] { bv(6 /*PASS_C2_V1*/), bv(7 /*PASS_C2_V2*/) } );
+ public final InPort count;
+ public PunctuatorModule(long punc) {
+ this.punc = punc;
+ this.count = new DockInPort("in2", ship.getDock("in2"), 0, new BitVector[] { null, bv(1), bv(punc) });
+ }
+ }
+
+ public class AluModule extends Module {
+ public final Ship ship = pool.allocateShip("Alu");
+ public final InPort in1 = new DockInPort("in1", ship.getDock("in1"));
+ public final InPort in2 = new DockInPort("in2", ship.getDock("in2"));
+ public final InPort inOp = new DockInPort("inOp", ship.getDock("inOp"));
+ public final OutPort out = new DockOutPort("out", ship.getDock("out"));
+ public AluModule() { }
+ }
+
+ public class DownCounterModule extends Module {
+ public final Ship ship = pool.allocateShip("Counter");
+ public final InPort start = new DockInPort("in1", ship.getDock("in1"));
+ public final InPort incr = new DockInPort("in2", ship.getDock("in2"));
+ public final InPort inOp = new DockInPort("inOp", ship.getDock("inOp"), 0, new BitVector[] { bv(12 /*COUNTDOWN*/) });
+ public final OutPort out = new DockOutPort("out", ship.getDock("out"));
+ public DownCounterModule() { }
+ }
+
+ public class RepeatModule extends Module {
+ public final Ship ship = pool.allocateShip("Counter");
+ public final InPort count = new DockInPort("in1", ship.getDock("in1"));
+ public final InPort val = new DockInPort("in2", ship.getDock("in2"));
+ public final InPort inOP = new DockInPort("inOp", ship.getDock("inOp"), 0, new BitVector[] { bv(1 /*REPEAT_C1_V2*/) });
+ public final OutPort out = new DockOutPort("out", ship.getDock("out"));
+ public RepeatModule() { }
+ }
+
+ public class SortedMergeModule extends Module {
+ public final Ship ship = pool.allocateShip("Alu");
+ public final InPort in1 = new DockInPort("in1", ship.getDock("in1"));
+ public final InPort in2 = new DockInPort("in2", ship.getDock("in2"));
+ public final InPort inOp = new DockInPort("inOp", ship.getDock("inOp"), 0, new BitVector[] { bv(9 /*MAXMERGE*/) });
+ public final OutPort out = new DockOutPort("out", ship.getDock("out"));
+ public SortedMergeModule() { }
+ }
+
+ public class MemoryModule extends Module {
+ public final Ship ship;
+ public final InPort inAddrRead1;
+ public final InPort inAddrRead2;
+ //public final InPort inAddrWrite;
+ //public final InPort inDataWrite;
+ public final OutPort outRead1;
+ public final OutPort outRead2;
+ public MemoryModule(Ship memoryShip) {
+ this.ship = memoryShip;
+ this.inAddrRead1 = new InPort("inAddrRead1") {
+ public void recvToken(Context.LoopFactory lf) { lf.recvToken(); }
+ public void sendWord(Context.LoopFactory lf) { lf.sendWord(ship.getDock("inAddrRead").getDataDestination(), new BitVector(1).set(0)); }
+ public void build(Context ctx) { }
+ public void reset(Context ctx, int phase) {
+ if (phase==2) {
+ torpedoes.add(ship.getDock("inAddrRead"));
+ torpedoes.add(ship.getDock("out"));
+ }
+ }
+ };
+ this.inAddrRead2 = new InPort("inAddrRead2") {
+ public void recvToken(Context.LoopFactory lf) { lf.recvToken(); }
+ public void sendWord(Context.LoopFactory lf) { lf.sendWord(ship.getDock("inAddrRead").getDataDestination(), new BitVector(1).set(1)); }
+ public void build(Context ctx) { }
+ public void reset(Context ctx, int phase) {
+ if (phase==2) {
+ torpedoes.add(ship.getDock("inAddrRead"));
+ torpedoes.add(ship.getDock("out"));
+ }
+ }
+ };
+ 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) { }
+ };
+ 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 build(Context ctx) {
+ super.build(ctx);
+ Context.LoopFactory lf;
+
+ lf = ctx.new LoopFactory(ship.getDock("inAddrRead"), 0);
+ lf.abortLoopIfTorpedoPresent();
+ lf.recvWord();
+ lf.setFlags(FlagFunction.ZERO.add(FlagC), FlagFunction.ZERO);
+ lf.setPredicate(Predicate.NotFlagA);
+ lf.sendToken(ship.getDock("out").getDataDestination(), new BitVector(1).set(0));
+ lf.setPredicate(Predicate.FlagA);
+ lf.sendToken(ship.getDock("out").getDataDestination(), new BitVector(1).set(1));
+ lf.setPredicate(null);
+ lf.deliver();
+
+ lf = ctx.new LoopFactory(ship.getDock("out"), 0);
+ lf.abortLoopIfTorpedoPresent();
+ lf.collectWord();
+ lf.abortLoopIfTorpedoPresent();
+ lf.recvToken();
+ lf.setFlags(FlagFunction.ZERO.add(FlagC), FlagFunction.ZERO);
+ if (outRead1.peer != null) {
+ lf.setPredicate(Predicate.NotFlagA);
+ outRead1.peer.sendWord(lf);
+ }
+ if (outRead2.peer != null) {
+ lf.setPredicate(Predicate.FlagA);
+ outRead2.peer.sendWord(lf);
+ }
+ lf.setPredicate(null);
+ }
+ }
+
+ public static void main(String[] s) throws Exception {
+ Fleet fleet = new Fpga();
+ Random random = new Random(System.currentTimeMillis());
+ long[] vals = new long[256];
+ for(int i=0; i<vals.length; i++) {
+ vals[i] = Math.abs(random.nextInt());
+ }
+
+ FleetProcess fp;
+ int stride = 1;
+ fp = null;
+ while(stride < vals.length) {
+ if (fp==null) fp = fleet.run(new Instruction[0]);
+ System.out.println("stride " + stride);
+ vals = mergeSort(fp, fleet, vals, stride);
+ stride = stride * 2;
+ //fp.terminate(); fp = null;
+ System.out.println();
+ System.out.println("results:");
+ for(int i=0; i<vals.length; i++)
+ System.out.println(vals[i]);
+ }
+ }
+
+ // won't verify that the switch fabric is empty, however
+ public static void verifyClean(FleetProcess fp) {
+ Ship debug = fp.getFleet().getShip("Debug", 0);
+ Dock debugIn = debug.getDock("in");
+
+ Context ctx;
+ Context.LoopFactory lf;
+
+ ctx = new Context(fp.getFleet());
+ lf = ctx.new LoopFactory(debugIn, 1);
+ lf.literal(12);
+ lf.deliver();
+ lf.literal(5);
+ lf.deliver();
+ ArrayList<Instruction> ai = new ArrayList<Instruction>();
+ ctx.emit(ai);
+ for(Instruction ins : ai) fp.sendInstruction(ins);
+ fp.flush();
+
+ System.out.println("checking debug.in");
+ if (fp.recvWord().toLong() != 12) throw new RuntimeException("debug dock not properly initialized");
+ if (fp.recvWord().toLong() != 5) throw new RuntimeException("debug dock not properly initialized");
+
+ int k = 0;
+ for(Ship ship : fp.getFleet())
+ if (!"Debug".equals(ship.getType()))
+ for (Dock dock : ship) {
+ System.out.println("checking " + dock);
+
+ k = (k + 23) % 65535;
+ ctx = new Context(fp.getFleet());
+ lf = ctx.new LoopFactory(debugIn, 1);
+ lf.literal(k);
+ lf.recvToken();
+ lf.deliver();
+ lf = ctx.new LoopFactory(dock, 1);
+ lf.sendToken(debugIn.getDataDestination());
+ ai = new ArrayList<Instruction>();
+ ctx.emit(ai);
+ for(Instruction ins : ai) fp.sendInstruction(ins);
+ fp.flush();
+
+ if (fp.recvWord().toLong() != k)
+ throw new RuntimeException(dock+" not properly initialized");
+ }
+ }
+
+ // FIXME: numbers seem to get duplicated when stride=2
+ public static long[] mergeSort(FleetProcess fp, Fleet fleet, long[] vals, int stride_length) throws Exception {
+
+ BitVector[] mem = new BitVector[vals.length];
+ for(int i=0; i<mem.length; i++) mem[i] = new BitVector(fleet.getWordWidth()).set(vals[i]);
+
+ Ship memoryShip = fleet.getShip("DRAM", 0);
+ Gadgets.writeMem(fp, memoryShip, 0, mem);
+
+ //////////////////////////////////////////////////////////////////////////////
+
+ Process proc = new Process(fleet);
+ DebugModule dm = proc.new DebugModule();
+
+ int end_of_data = vals.length;
+ int num_strides = end_of_data / (stride_length * 2);
+
+ MemoryModule mm = proc.new MemoryModule(memoryShip);
+ SortedMergeModule sm = proc.new SortedMergeModule();
+
+
+ for(int i=0; i<2; i++) {
+
+ Module.OutPort stride_length_1 = proc.new OnceModule(stride_length).out;
+ Module.OutPort stride_length_2 = proc.new OnceModule(stride_length).out;
+ Module.OutPort twice_stride_length_1 = proc.new OnceModule(stride_length*2).out;
+ Module.OutPort end_of_data_1 = proc.new OnceModule(end_of_data + i*stride_length).out;
+
+ Module.OutPort num_strides_1 = proc.new OnceModule(num_strides).out;
+ Module.OutPort num_strides_2 = proc.new OnceModule(num_strides).out;
+
+ RepeatModule r0 = proc.new RepeatModule();
+ RepeatModule r1 = proc.new RepeatModule();
+ RepeatModule r2 = proc.new RepeatModule();
+ DownCounterModule c0 = proc.new DownCounterModule();
+ DownCounterModule c1 = proc.new DownCounterModule();
+ ForeverModule fmm = proc.new ForeverModule(1);
+ ForeverModule fmm2 = proc.new ForeverModule(2); // 2=ADD
+ AluModule alu = proc.new AluModule();
+
+ stride_length_1.connect(r0.val);
+ num_strides_1.connect(r0.count);
+ r0.out.connect(c0.start);
+ fmm.out.connect(c0.incr);
+ c0.out.connect(alu.in2);
+
+ end_of_data_1.connect(c1.start);
+ twice_stride_length_1.connect(c1.incr);
+ c1.out.connect(r1.val);
+ stride_length_2.connect(r2.val);
+ num_strides_2.connect(r2.count);
+ r2.out.connect(r1.count);
+ r1.out.connect(alu.in1);
+ fmm2.out.connect(alu.inOp);
+
+ alu.out.connect(i==0 ? mm.inAddrRead1 : mm.inAddrRead2);
+
+ ForeverModule fm = proc.new ForeverModule(stride_length);
+ PunctuatorModule punc = proc.new PunctuatorModule(-1);
+ fm.out.connect(punc.count);
+ (i==0 ? mm.outRead1 : mm.outRead2).connect(punc.val);
+ punc.out.connect(i==0 ? sm.in1 : sm.in2);
+ }
+
+ ForeverModule fm = proc.new ForeverModule(2*stride_length);
+ UnPunctuatorModule unpunc = proc.new UnPunctuatorModule();
+ sm.out.connect(unpunc.val);
+ fm.out.connect(unpunc.count);
+ unpunc.out.connect(dm.in);
+
+ //////////////////////////////////////////////////////////////////////////////
+
+ Context ctx = new Context(fp.getFleet());
+ ctx.setAutoflush(true);
+
+ ArrayList<Instruction> ai = new ArrayList<Instruction>();
+ proc.build(ctx);
+ ctx.emit(ai);
+ for(Instruction ins : ai) {
+ System.out.println(ins);
+ fp.sendInstruction(ins);
+ }
+ fp.flush();
+
+ System.out.println("reading back...");
+ int inc=0;
+ for(int i=0; i<vals.length; i++) {
+ inc++;
+ BitVector bv = fp.recvWord();
+ System.out.println("\r"+bv + " " + bv.toLong() + " #read="+inc);
+ mem[i] = bv;
+ }
+ System.out.println("\rdone. ");
+ long[] ret = new long[vals.length];
+ for(int i=0; i<ret.length; i++) ret[i] = mem[ret.length-i-1].toLong();
+
+ //if (true) return ret;
+
+ Context ctx2 = new Context(fp.getFleet());
+ Dock debugIn = fleet.getShip("Debug",0).getDock("in");
+ Dock fred = debugIn;
+ fp.sendToken(debugIn.getInstructionDestination());
+
+ Context.LoopFactory lf = ctx2.new LoopFactory(debugIn, 0);
+ lf.literal(0);
+ lf.abortLoopIfTorpedoPresent();
+ lf.recvToken();
+ lf.deliver();
+
+ ctx2.emit(ai = new ArrayList<Instruction>());
+ for(Instruction ins : ai)
+ fp.sendInstruction(ins);
+ fp.flush();
+
+ int count = 0;
+
+ for(int phase=0; phase<=2; phase++) {
+ System.out.println("== phase "+phase+" ==================================================================");
+ ctx2 = new Context(fp.getFleet());
+ proc.reset(ctx2, phase);
+ for(Dock dock : torpedoes) fp.sendToken(dock.getInstructionDestination());
+ ctx2.emit(ai = new ArrayList<Instruction>());
+ for(Instruction ins : ai) fp.sendInstruction(ins);
+ fp.flush();
+ System.out.println("flushed");
+ for(int ii=0; ii<reset_count; ii++)
+ System.out.print("\r phase "+phase+" ==> " + fp.recvWord().toLong() + " " + (ii+1) + " / " + reset_count);
+ System.out.println();
+ }
+
+ /*
+ ctx2 = new Context(fp.getFleet());
+ ai = new ArrayList<Instruction>();
+ for(Ship ship : ctx.allocatedShips)
+ if (!ship.getType().equals("Debug"))
+ for(Dock dock : ship)
+ if (dock.isInputDock()) {
+ lf = ctx2.new LoopFactory(dock, 0);
+ lf.recvWord();
+
+ }
+ */
+
+ fp.sendToken(debugIn.getInstructionDestination());
+ fp.flush();
+
+ //System.out.println("verifying cleanup:");
+ //verifyClean(fp);
+ return ret;
+ }
+
+ private BitVector[] longsToBitVectors(long[] initialValues) {
+ BitVector[] bv = new BitVector[initialValues.length];
+ for(int i=0; i<initialValues.length; i++)
+ bv[i] = new BitVector(fleet.getWordWidth()).set(initialValues[i]);
+ return bv;
+ }
+}
+
+