3a83ccf163a27771d9accd4e7a901330cc6331c6
[fleet.git] / src / edu / berkeley / fleet / dataflow / Process.java
1 package edu.berkeley.fleet.dataflow;
2 import edu.berkeley.fleet.loops.*;
3 import java.util.concurrent.Semaphore;
4 import java.util.*;
5 import java.net.*;
6 import edu.berkeley.fleet.two.*;
7 import edu.berkeley.fleet.api.*;
8 import edu.berkeley.fleet.fpga.*;
9 import edu.berkeley.fleet.api.Instruction.*;
10 import edu.berkeley.fleet.api.Instruction.Set;
11 import edu.berkeley.fleet.api.Instruction.Set.*;
12 import static edu.berkeley.fleet.api.Predicate.*;
13 import static edu.berkeley.fleet.util.BitManipulations.*;
14
15 // does peer.recvWord() have to honor the currently-set predicate?
16
17 // public class ReplaceModule extends Module { }
18 // public class CountMergeModule extends Module { }
19 // public class SortMergeModule extends Module { }
20 // public class FanOutModule extends Module { }
21 // public class MemoryModule extends Module { }
22 // public class DoneModule extends Module { }
23
24 public class Process {
25
26     public static int reset_count = 0;
27     public static HashSet<Dock> torpedoes = new HashSet<Dock>();
28
29     public final Fleet    fleet;
30     public final ShipPool pool;
31
32     public Process(Fleet fleet) {
33         this.fleet = fleet;
34         this.pool  = new ShipPool(fleet);
35     }
36
37     private HashSet<Module> modules = new HashSet<Module>();
38
39     public void build(Context ctx) {
40         for(Module mod : modules)
41             mod.build(ctx);
42     }
43     public void reset(Context ctx, int phase, Destination ackDestination) {
44         reset_count = 0;
45         torpedoes.clear();
46         for(Module mod : modules)
47             mod.reset(ctx, phase, ackDestination);
48     }
49
50     public class Module {
51
52         void doReset(Context ctx, int phase, Dock dock, Port peer, Destination ackDestination, boolean peerUsed) {
53             if (dock.getShip().getType().equals("Debug")) return;
54
55             switch(phase) {
56
57                 // Phase 0: torpedo every output dock, put it in
58                 // collecting mode.  Cannot combine with phase 1,
59                 // because until output docks are in vacuum mode we
60                 // cannot be sure that the tokens to the input docks
61                 // will eventually succeed.  This may cause the
62                 // instructions sent after the tokens to back up into
63                 // the switch fabric.
64                 case 0: {
65                     if (!dock.isInputDock()) {
66                         torpedoes.add(dock);
67                         LoopFactory lf = new LoopFactory(ctx, dock, 1);
68                         lf.sendToken(ackDestination);
69                         lf = lf.makeNext(0);
70                         lf.abortLoopIfTorpedoPresent();
71                         lf.collectWord();
72                         reset_count++;
73                     }
74                     break;
75                 }
76
77                 // Phase 1: torpedo every input dock, put it in loopback mode
78                 case 1: {
79                     if (dock.isInputDock()) {
80                         torpedoes.add(dock);
81                         LoopFactory lf = new LoopFactory(ctx, dock, 1);
82                         lf.sendToken(ackDestination);
83
84                         // FIXME: this won't work right for ports that
85                         // get "shared" by two senders (for example,
86                         // inAddrRead1/2)
87
88                         if (peerUsed && peer!=null) {
89                             lf = lf.makeNext(0);
90                             lf.abortLoopIfTorpedoPresent();
91                             ((OutPort)peer).recvWord(lf);
92                             ((OutPort)peer).sendToken(lf);
93                         }
94                         reset_count++;
95                     }
96                     break;
97                 }
98
99                 // Phase 2: torpedo every output dock, have it absorb tokens
100                 case 2: {
101                     if (!dock.isInputDock()) {
102                         torpedoes.add(dock);
103                         LoopFactory lf = new LoopFactory(ctx, dock, 1);
104                         if (peer != null)
105                             for(int i=0; i<((InPort)peer).getTokensToAbsorb(); i++)
106                                 lf.recvToken();
107                         lf.sendToken(ackDestination);
108                         reset_count++;
109                     }
110                     break;
111                 }
112
113                 // Phase 3: torpedo every input dock, and we're done
114                 case 3: {
115                     if (dock.isInputDock()) {
116                         if (peerUsed && peer!=null) {
117                             torpedoes.add(dock);
118                         }
119                         LoopFactory lf = new LoopFactory(ctx, dock, 1);
120                         lf.sendToken(ackDestination);
121                         reset_count++;
122                     }
123                     break;
124                 }
125
126
127             }
128         }
129
130         public Module() {
131             Process.this.modules.add(this);
132         }
133
134         private HashMap<String,Port> ports = new HashMap<String,Port>();
135
136         public InPort  getInPort(String name)  { return (InPort)ports.get(name); }
137         public OutPort getOutPort(String name) { return (OutPort)ports.get(name); }
138         
139         public void build(Context ctx) { for(Port p : ports.values()) p.build(ctx); }
140         public void reset(Context ctx, int phase, Destination ackDestination) {
141             for(Port p : ports.values()) p.reset(ctx, phase, ackDestination);
142         }
143
144         public abstract class Port {
145             public final String name;
146             public Port(String name) {
147                 this.name = name;
148                 if (Module.this.ports.get(name)!=null) throw new RuntimeException();
149                 Module.this.ports.put(name,this);
150             }
151             public abstract void build(Context ctx);
152             public abstract void reset(Context ctx, int phase, Destination ackDestination);
153         }
154
155         public abstract class InPort extends Port {
156             OutPort peer;
157             public InPort(String name) { super(name); }
158             public void connect(OutPort peer) {
159                 this.setPeer(peer);
160                 peer.setPeer(this);
161             }
162             public void setPeer(OutPort peer) {
163                 if (this.peer!=null) throw new RuntimeException("cannot call setPeer() twice");
164                 this.peer = peer;
165             }
166
167             /** this port's peer (an OutPort) invokes this to have "recvToken" or equivalent inserted */
168             public abstract void recvToken(LoopFactory loopfactory_at_output_dock);
169             /** this port's peer (an OutPort) invokes this to have "sendWord" or equivalent inserted */
170             public abstract void sendWord(LoopFactory loopfactory_at_output_dock);
171
172             public int getTokensToAbsorb() { return 0; }
173         }
174
175         public abstract class OutPort extends Port {
176             InPort peer;
177             public OutPort(String name) { super(name); }
178             public void connect(InPort peer) {
179                 this.setPeer(peer);
180                 peer.setPeer(this);
181             }
182             public void setPeer(InPort peer) {
183                 if (this.peer!=null) throw new RuntimeException("cannot call setPeer() twice");
184                 this.peer = peer;
185             }
186
187             /** this port's peer (an InPort) invokes this to have "sendToken" or equivalent inserted */
188             public abstract void sendToken(LoopFactory loopfactory_at_input_dock);
189             /** this port's peer (an InPort) invokes this to have "recvWord" or equivalent inserted */
190             public abstract void recvWord(LoopFactory loopfactory_at_input_dock);
191         }
192
193         public final class DockInPort extends InPort {
194             final Dock dock;
195             int count;
196             BitVector[] pattern;
197             public DockInPort(String name, Dock dock) { this(name, dock, 0); }
198             public DockInPort(String name, Dock dock, int count) { this(name, dock, count, new BitVector[] { null }); }
199             public DockInPort(String name, Dock dock, int count, BitVector[] pattern) {
200                 super(name);
201                 this.dock = dock;
202                 this.count = count;
203                 this.pattern = pattern;
204             }
205             public void recvToken(LoopFactory lf) { lf.recvToken(); }
206             public void sendWord(LoopFactory lf) { lf.sendWord(dock.getDataDestination()); }
207             public void build(Context ctx) { build(ctx, new LoopFactory(ctx, dock, 1)); }
208             // number-in-flight is considered a property of the input dock in a pair
209             public int getInflight() { return 4; }
210             //public int getInflight() { return 1; }
211             public int getTokensToAbsorb() { return getInflight(); }
212             private boolean peerUsed() {
213                 if (peer==null) return false;
214                 for(int i=0; i<pattern.length; i++) if (pattern[i]==null) return true;
215                 return false;
216             }
217             public void reset(Context ctx, int phase, Destination ackDestination) {
218                 doReset(ctx, phase, dock, peer, ackDestination, peerUsed());
219             }
220             protected void build(Context ctx, LoopFactory lf) {
221                 int inflight = (count != 0 && count < getInflight()) ? count : getInflight();
222
223                 if (peer!=null)
224                     for(int i=0; i<inflight; i++) peer.sendToken(lf);
225
226                 lf = lf.makeNext(count, true);
227                 for(int i=0; i<pattern.length; i++) {
228                     if (pattern[i]==null) {
229                         if (peer!=null) {
230                             lf.abortLoopIfTorpedoPresent();
231                             peer.recvWord(lf);
232                             peer.sendToken(lf);
233                             lf.deliver();
234                         } else {
235                             lf.interruptibleNop();
236                         }
237                     } else {
238                         lf.literal(pattern[i]);
239                         lf.abortLoopIfTorpedoPresent();
240                         lf.deliver();
241                     }
242                 }
243
244                 if (count!=0) {
245                     // "torpedoable nop" to keep the dock in a receptive state
246                     lf.abortLoopIfTorpedoPresent();
247                     lf.recvToken();
248                 }
249             }
250             public BitVector getConstant(String constantName) {
251                 return dock.getConstant(constantName);
252             }
253         }
254
255         public /*final*/ class DockOutPort extends OutPort {
256             public final Dock dock;
257             public final int count;
258             public DockOutPort(String name, Dock dock) { this(name, dock, 0); }
259             public DockOutPort(String name, Dock dock, int count) { super(name); this.dock = dock; this.count = count; }
260             public void sendToken(LoopFactory lf) { lf.sendToken(dock.getDataDestination()); }
261             public void recvWord(LoopFactory lf) { lf.recvWord(); }
262             public void build(Context ctx) { build(ctx, new LoopFactory(ctx, dock, 1)); }
263             protected void build(Context ctx, LoopFactory lf) {
264                 if (peer==null) return;
265                 lf = lf.makeNext(count);
266                 lf.abortLoopIfTorpedoPresent();
267                 peer.recvToken(lf);
268                 lf.collectWord();
269                 peer.sendWord(lf);
270             }
271             public void reset(Context ctx, int phase, Destination ackDestination) {
272                 doReset(ctx, phase, dock, peer, ackDestination, true);
273             }
274         }
275     }
276
277     private static BitVector bv(long l) { return new BitVector(/*FIXME fleet.getWordWidth()*/37).set(l); }
278     private static BitVector[] bv(long[] l) {
279         BitVector[] ret = new BitVector[l.length];
280         for(int i=0; i<ret.length; i++) ret[i] = bv(l[i]);
281         return ret;
282     }
283
284     /**
285      *  Deliver the constant at out forever.  Flow control in<->out is
286      *  maintained, but out is not flow-controlled, so be sure
287      *  that every datum sent there is consumed synchronously wiht
288      *  data items sent to out.
289      */
290     public class ForeverModule extends Module {
291         private BitVector bv;
292         public final OutPort out = new OutPort("out") {
293                 public void sendToken(LoopFactory lf) { }
294                 public void recvWord(LoopFactory lf) { }
295                 public void build(Context ctx) { }
296                 public void reset(Context ctx, int phase, Destination ackDestination) { }
297                 public void setPeer(InPort peer) {
298                     this.peer = peer;
299                     DockInPort pip = ((DockInPort)peer);
300                     for(int i=0; i<pip.pattern.length; i++) {
301                         if (pip.pattern[i]==null)
302                             pip.pattern[i] = bv;
303                     }
304                 }
305             };
306         public ForeverModule(long l) { this(new BitVector(fleet.getWordWidth()).set(l)); }
307         public ForeverModule(final BitVector bv) { this.bv = bv; }
308     }
309
310     public class OnceModule extends Module {
311         private BitVector bv;
312         public final OutPort out = new OutPort("out") {
313                 public void sendToken(LoopFactory lf) { }
314                 public void recvWord(LoopFactory lf) { }
315                 public void build(Context ctx) { }
316                 public void reset(Context ctx, int phase, Destination ackDestination) { }
317                 public void setPeer(InPort peer) {
318                     this.peer = peer;
319                     DockInPort pip = ((DockInPort)peer);
320                     BitVector[] pip_pattern = pip.pattern;
321                     BitVector[] temp = new BitVector[pip_pattern.length * 2];
322                     int j = 0;
323                     int i = 0;
324                     boolean done = false;
325                     // FIXME: if peer.count is already 1, this gets simpler and different
326                     for(i=0; i<temp.length; i++) {
327                         if (pip_pattern[j] != null) {
328                             temp[i] = pip_pattern[j];
329                         } else {
330                             if (done) break;
331                             done = true;
332                             temp[i] = bv;
333                         }
334                         j++;
335                         if (j >= pip_pattern.length) j = 0;
336                     }
337                     pip.pattern = new BitVector[i];
338                     System.arraycopy(temp, 0, pip.pattern, 0, i);
339                     pip.count = 1;
340                 }
341             };
342         public OnceModule(long l) { this(new BitVector(fleet.getWordWidth()).set(l)); }
343         public OnceModule(final BitVector bv) { this.bv = bv; }
344     }
345
346     public class DebugModule extends Module {
347         public final Ship ship = pool.allocateShip("Debug");
348         public final InPort in = new DockInPort("in", ship.getDock("in"));
349         // NOTE: shutdown needs to treat this specially
350         public DebugModule() { }
351     }
352
353     public class UnPunctuatorModule extends Module {
354         private final Ship    ship  = pool.allocateShip("Counter");
355         public  final OutPort out   = new DockOutPort("out", ship.getDock("out"));
356         public  final InPort  val   = new DockInPort("in1",  ship.getDock("in1"));
357         public  final InPort  count = new DockInPort("in2",  ship.getDock("in2"), 0, new BitVector[] { null, bv(1) });
358         public  final InPort  op    = new DockInPort("inOp", ship.getDock("inOp"), 0, new BitVector[] {
359                 ship.getDock("inOp").getConstant("PASS_C2_V1"),
360                 ship.getDock("inOp").getConstant("DROP_C2_V1") } );
361         public UnPunctuatorModule() { }
362     }
363
364     public class PunctuatorModule extends Module {
365         private final long    punc;
366         private final Ship    ship  = pool.allocateShip("Counter");
367         public  final OutPort out   = new DockOutPort("out", ship.getDock("out"));
368         public  final InPort  val   = new DockInPort("in1",  ship.getDock("in1"));
369         public  final InPort  op    = new DockInPort("inOp", ship.getDock("inOp"), 0, new BitVector[] {
370                 ship.getDock("inOp").getConstant("PASS_C2_V1"),
371                 ship.getDock("inOp").getConstant("PASS_C2_V2") } );
372         public  final InPort  count;
373         public PunctuatorModule(long punc) {
374             this.punc = punc;
375             this.count = new DockInPort("in2",  ship.getDock("in2"), 0, new BitVector[] { null, bv(1), bv(punc) });
376         }
377     }
378
379     public class AluModule extends Module {
380         public final Ship    ship = pool.allocateShip("Alu");
381         public final InPort  in1 = new DockInPort("in1",  ship.getDock("in1"));
382         public final InPort  in2 = new DockInPort("in2",  ship.getDock("in2"));
383         public final InPort  inOp = new DockInPort("inOp", ship.getDock("inOp"));
384         public final OutPort out  = new DockOutPort("out", ship.getDock("out"));
385         public AluModule() { }
386     }
387
388     public class DownCounterModule extends Module {
389         public final Ship    ship  = pool.allocateShip("Counter");
390         public final InPort  start = new DockInPort("in1",  ship.getDock("in1"));
391         public final InPort  incr  = new DockInPort("in2",  ship.getDock("in2"));
392         public final InPort  inOp  = new DockInPort("inOp", ship.getDock("inOp"), 0, new BitVector[] {
393                 ship.getDock("inOp").getConstant("COUNT") });
394         public final OutPort out   = new DockOutPort("out", ship.getDock("out"));
395         public DownCounterModule() { }
396     }
397
398     public class RepeatModule extends Module {
399         public final Ship    ship   = pool.allocateShip("Counter");
400         public final InPort  count  = new DockInPort("in1",  ship.getDock("in1"));
401         public final InPort  val    = new DockInPort("in2",  ship.getDock("in2"));
402         public final InPort  inOP   = new DockInPort("inOp", ship.getDock("inOp"), 0, new BitVector[] {
403                 ship.getDock("inOp").getConstant("REPEAT_C1_V2") });
404         public final OutPort out    = new DockOutPort("out", ship.getDock("out"));
405         public RepeatModule() { }
406     }
407
408     public class SortedMergeModule extends Module {
409         public final Ship    ship = pool.allocateShip("Alu");
410         public final InPort  in1  = new DockInPort("in1",  ship.getDock("in1"));
411         public final InPort  in2  = new DockInPort("in2",  ship.getDock("in2"));
412         public final InPort  inOp = new DockInPort("inOp", ship.getDock("inOp"), 0, new BitVector[] {
413                 ship.getDock("inOp").getConstant("MAXMERGE") });
414         public final OutPort out  = new DockOutPort("out", ship.getDock("out"));
415         public SortedMergeModule() { }
416     }
417
418     public class MemoryModule extends Module {
419         public final Ship    ship;
420         public final InPort  inCBD;
421         public final InPort  inAddrRead1;
422         public final InPort  inAddrRead2;
423         public final InPort  inAddrWrite;
424         public final InPort  inDataWrite;
425         public final OutPort outRead1;
426         public final OutPort outRead2;
427         public final OutPort outWrite;
428         public MemoryModule(Ship memoryShip) {
429             this.ship = memoryShip;
430             this.inCBD        = ship.getType().equals("Memory") ? new DockInPort("inCBD", ship.getDock("inCBD")) : null;
431             this.inAddrWrite  = new DockInPort("inAddrWrite", ship.getDock("inAddrWrite"));
432             this.inDataWrite  = new DockInPort("inDataWrite", ship.getDock("inDataWrite"));
433             this.inAddrRead1  = new InPort("inAddrRead1") {
434                     public void recvToken(LoopFactory lf) { lf.recvToken(); }
435                     public void sendWord(LoopFactory lf) { lf.sendWord(ship.getDock("inAddrRead").getDataDestination(), new BitVector(1).set(0)); }
436                     public void build(Context ctx) { }
437                     public int getTokensToAbsorb() { return outRead1.peer.getTokensToAbsorb(); }
438                     public void reset(Context ctx, int phase, Destination ackDestination) {
439                         doReset(ctx, phase, ship.getDock("inAddrRead"), null, ackDestination, false);
440                     }
441                 };
442             this.inAddrRead2  = new InPort("inAddrRead2") {
443                     public void recvToken(LoopFactory lf) { lf.recvToken(); }
444                     public void sendWord(LoopFactory lf) { lf.sendWord(ship.getDock("inAddrRead").getDataDestination(), new BitVector(1).set(1)); }
445                     public void build(Context ctx) { }
446                     public int getTokensToAbsorb() { return outRead2.peer.getTokensToAbsorb(); }
447                     public void reset(Context ctx, int phase, Destination ackDestination) { }
448                 };
449             this.outRead1 = new OutPort("outRead1") {
450                     public void sendToken(LoopFactory lf) { inAddrRead1.peer.sendToken(lf); }
451                     public void recvWord(LoopFactory lf) { lf.recvWord(); }
452                     public void build(Context ctx) { }
453                     public void reset(Context ctx, int phase, Destination ackDestination) { }
454                 };
455             this.outRead2 = new OutPort("outRead2") {
456                     public void sendToken(LoopFactory lf) { inAddrRead2.peer.sendToken(lf); }
457                     public void recvWord(LoopFactory lf) { lf.recvWord(); }
458                     public void build(Context ctx) { }
459                     public void reset(Context ctx, int phase, Destination ackDestination) { }
460                 };
461             this.outWrite = new DockOutPort("out", ship.getDock("out")) {
462                     protected void build(Context ctx, LoopFactory lf) {
463                         lf = lf.makeNext(0);
464                         lf.abortLoopIfTorpedoPresent();
465                         lf.collectWord();
466                         
467                         lf.setFlags(FlagFunction.ZERO, FlagFunction.ZERO.add(FlagC));
468                         if (this.peer != null) {
469                             lf.setPredicate(Predicate.FlagB);
470                             lf.literal(77);
471                             lf.abortLoopIfTorpedoPresent();
472                             this.peer.recvToken(lf);
473                             this.peer.sendWord(lf);
474                         }
475                         
476                         lf.setPredicate(Predicate.NotFlagB);
477                         lf.abortLoopIfTorpedoPresent();
478                         lf.recvToken();
479                         lf.setFlags(FlagFunction.ZERO.add(NotFlagC).add(FlagB), FlagFunction.ZERO.add(FlagC).add(FlagB));
480                         if (outRead1.peer != null) {
481                             lf.setPredicate(Predicate.NotFlagB);
482                             outRead1.peer.sendWord(lf);
483                         }
484                         if (outRead2.peer != null) {
485                             lf.setPredicate(Predicate.NotFlagA);
486                             outRead2.peer.sendWord(lf);
487                         }
488                         lf.setPredicate(null);
489                     }
490                 };
491         }
492         public void build(Context ctx) {
493             super.build(ctx);
494             LoopFactory lf;
495
496             lf = new LoopFactory(ctx, ship.getDock("inAddrRead"), 0);
497             lf.abortLoopIfTorpedoPresent();
498             lf.recvWord();
499             lf.setFlags(FlagFunction.ZERO.add(FlagC), FlagFunction.ZERO);
500             lf.setPredicate(Predicate.NotFlagA);
501             lf.sendToken(ship.getDock("out").getDataDestination(), new BitVector(1).set(0));
502             lf.setPredicate(Predicate.FlagA);
503             lf.sendToken(ship.getDock("out").getDataDestination(), new BitVector(1).set(1));
504             lf.setPredicate(null);
505             lf.deliver();
506         }
507     }
508
509     public static void main(String[] s) throws Exception {
510         Fleet fleet = new Fpga();
511         //Fleet fleet = new Interpreter(false);
512
513         Random random = new Random(System.currentTimeMillis());
514         long[] vals = new long[256];
515         for(int i=0; i<vals.length; i++) {
516             vals[i] = Math.abs(random.nextInt());
517         }
518
519         Ship mem1 = fleet.getShip("Memory", 0);
520         Ship mem2 = fleet.getShip("Memory", 1);
521         //Ship mem2 = fleet.getShip("DDR2", 0);
522
523         FleetProcess fp;
524         int stride = 1;
525         fp = null;
526
527         fp = fleet.run(new Instruction[0]);
528         MemoryUtils.writeMem(fp, mem1, 0, bv(vals));
529         int vals_length = vals.length;
530
531         // Disable readback/writeback inside the loop
532         vals = null;
533
534         while(stride < vals_length) {
535             
536             // reset the FleetProcess
537             //fp.terminate(); fp = null;
538
539             System.out.println("stride " + stride);
540
541             // if we reset the FleetProcess, restart it
542             if (fp==null) fp = fleet.run(new Instruction[0]);
543
544             // do the mergeSort
545             vals = mergeSort(fp, fleet, vals, vals_length, stride, mem1, mem2);
546
547             // verify the cleanup
548             //CleanupUtils.verifyClean(fp);
549
550             Ship mem = mem1; mem1=mem2; mem2=mem;
551
552             stride = stride * 2;
553             System.out.println();
554         }
555
556         BitVector[] bvs = new BitVector[vals_length];
557         MemoryUtils.readMem(fp, mem1, 0, bvs);
558         System.out.println("results:");
559         for(int i=0; i<vals_length; i++)
560             System.out.println(bvs[i].toLong());
561     }
562
563
564     public static long[] mergeSort(FleetProcess fp, Fleet fleet,
565                                    long[] vals, int vals_length, int stride_length,
566                                    Ship memoryShip1, Ship memoryShip2) throws Exception {
567
568         if (vals != null) {
569             BitVector[] mem = new BitVector[vals_length];
570             for(int i=0; i<mem.length; i++) mem[i] = new BitVector(fleet.getWordWidth()).set(vals[i]);
571             MemoryUtils.writeMem(fp, memoryShip1, 0, mem);
572         }
573
574         //////////////////////////////////////////////////////////////////////////////
575
576         Process proc = new Process(fleet);
577         DebugModule dm = proc.new DebugModule();
578
579         int end_of_data = vals_length;
580         int num_strides = end_of_data / (stride_length * 2);
581
582         MemoryModule mm  = proc.new MemoryModule(memoryShip1);
583         SortedMergeModule sm = proc.new SortedMergeModule();
584
585         // So far: we have four spare Counter ships; one can be used for resetting
586         for(int i=0; i<2; i++) {
587
588             DownCounterModule c0 = proc.new DownCounterModule();
589             DownCounterModule c1 = proc.new DownCounterModule();
590
591             c0.start.connect(proc.new ForeverModule(stride_length).out);
592             c0.incr.connect(proc.new ForeverModule(1).out);
593
594             c1.start.connect(proc.new OnceModule(end_of_data + i*stride_length).out);
595             c1.incr.connect(proc.new OnceModule(stride_length*2).out);
596
597             RepeatModule r1 = proc.new RepeatModule();
598             r1.val.connect(c1.out);
599             r1.count.connect(proc.new ForeverModule(stride_length).out);
600
601             AluModule alu = proc.new AluModule();
602             alu.in1.connect(r1.out);
603             alu.in2.connect(c0.out);
604             alu.inOp.connect(proc.new ForeverModule(((Module.DockInPort)alu.inOp).getConstant("ADD")).out);
605             alu.out.connect(i==0 ? mm.inAddrRead1 : mm.inAddrRead2);
606
607             PunctuatorModule punc = proc.new PunctuatorModule(-1);
608             punc.count.connect(proc.new ForeverModule(stride_length).out);
609             punc.val.connect(i==0 ? mm.outRead1 : mm.outRead2);
610             punc.out.connect(i==0 ? sm.in1 : sm.in2);
611         }
612
613         UnPunctuatorModule unpunc = proc.new UnPunctuatorModule();
614         unpunc.val.connect(sm.out);
615         unpunc.count.connect(proc.new ForeverModule(2*stride_length).out);
616
617         DownCounterModule cw = proc.new DownCounterModule();
618         cw.start.connect(proc.new OnceModule(end_of_data).out);
619         cw.incr.connect(proc.new OnceModule(1).out);
620
621         MemoryModule mm2 = proc.new MemoryModule(memoryShip2);
622         mm2.inAddrWrite.connect(cw.out);
623         mm2.inDataWrite.connect(unpunc.out);
624         mm2.outWrite.connect(dm.in);
625
626         //////////////////////////////////////////////////////////////////////////////
627
628         Context ctx = new Context(fp.getFleet());
629         ctx.setAutoflush(true);
630
631         ArrayList<Instruction> ai = new ArrayList<Instruction>();
632         proc.build(ctx);
633         ctx.emit(ai);
634         for(Instruction ins : ai) {
635             //System.out.println(ins);
636             fp.sendInstruction(ins);
637         }
638         fp.flush();
639
640         for(int i=0; i<vals_length; i++) {
641             System.out.print("\rreading back... " + i+"/"+vals_length+"  ");
642             BitVector rec = fp.recvWord();
643             System.out.print(" (prev result: " + rec + " = " + rec.toLong() + ")");
644         }
645         System.out.println("\rdone.                                                                    ");
646
647         //if (true) return ret;
648
649         Context ctx2 = new Context(fp.getFleet());
650         Dock debugIn = fleet.getShip("Debug",0).getDock("in");
651         Dock fred = debugIn;
652         fp.sendToken(debugIn.getInstructionDestination());
653         fp.flush();
654
655         LoopFactory lf = new LoopFactory(ctx2, debugIn, 0);
656         lf.literal(0);
657         lf.abortLoopIfTorpedoPresent();
658         lf.recvToken();
659         lf.deliver();
660
661         ctx2.dispatch(fp);
662         fp.flush();
663
664         int count = 0;
665
666         Ship counter = proc.pool.allocateShip("Counter");
667
668         for(int phase=0; phase<=3; phase++) {
669             System.out.println("== phase "+phase+" ==================================================================");
670             ctx2 = new Context(fp.getFleet());
671
672             Destination ackDestination = counter.getDock("in2").getDataDestination();
673             proc.reset(ctx2, phase, ackDestination);
674
675             Context ctx3 = new Context(fp.getFleet());
676             lf = new LoopFactory(ctx3, counter.getDock("inOp"), 1);
677             lf.literal("DROP_C1_V2");
678             lf.deliver();
679             lf.literal(5);
680             lf.deliver();
681             lf = new LoopFactory(ctx3, counter.getDock("in1"), 1);
682             lf.literal(reset_count-1);
683             lf.deliver();
684             lf.literal(1);
685             lf.deliver();
686             lf = new LoopFactory(ctx3, counter.getDock("in2"), 0);
687             lf.abortLoopIfTorpedoPresent();
688             lf.recvWord();
689             lf.deliver();
690             lf = new LoopFactory(ctx3, counter.getDock("out"), 1);
691             lf.collectWord();
692             lf.sendToken(counter.getDock("in2").getInstructionDestination());  // HACK: we don't check to make sure this hits
693             lf.sendToken(debugIn.getDataDestination());
694             ctx3.dispatch(fp);  // HACK: we don't check to make sure that this is "firmly in place"
695
696             for(Dock dock : torpedoes) fp.sendToken(dock.getInstructionDestination());
697             ctx2.dispatch(fp);
698             fp.flush();
699             System.out.println("flushed");
700
701             fp.recvWord();
702             System.out.println("phase done");
703
704             System.out.println();
705         }
706
707         fp.sendToken(debugIn.getInstructionDestination());
708         fp.flush();
709
710         //System.out.println("verifying cleanup:");
711         //CleanupUtils.verifyClean(fp);
712
713         System.out.println("reading back:");
714         long[] ret = null;
715         if (vals != null) {
716             ret = new long[vals_length];
717             BitVector[] mem = new BitVector[vals_length];
718             MemoryUtils.readMem(fp, memoryShip2, 0, mem);
719             for(int i=0; i<ret.length; i++) ret[i] = mem[i].toLong();
720         }
721         return ret;
722     }
723
724     private BitVector[] longsToBitVectors(long[] initialValues) {
725         BitVector[] bv = new BitVector[initialValues.length];
726         for(int i=0; i<initialValues.length; i++)
727             bv[i] = new BitVector(fleet.getWordWidth()).set(initialValues[i]);
728         return bv;
729     }
730 }
731
732