MemoryNode: make sure not to do phase 0 of reset on out port
[fleet.git] / src / edu / berkeley / fleet / dataflow / MemoryNode.java
1 package edu.berkeley.fleet.dataflow;
2 import java.util.*;
3 import edu.berkeley.fleet.loops.*;
4 import edu.berkeley.fleet.api.*;
5 import edu.berkeley.fleet.fpga.*;
6 import edu.berkeley.fleet.api.Instruction.*;
7 import edu.berkeley.fleet.api.Instruction.Set;
8 import edu.berkeley.fleet.api.Instruction.Set.*;
9 import static edu.berkeley.fleet.api.Predicate.*;
10
11
12 public class MemoryNode extends Node {
13     private final Ship    ship;
14     public final InPort  inCBD;
15     public final InPort  inAddrRead1;
16     public final InPort  inAddrRead2;
17     public final InPort  inAddrWrite;
18     public final InPort  inDataWrite;
19     public final OutPort outRead1;
20     public final OutPort outRead2;
21     public final OutPort outWrite;
22     public MemoryNode(DataFlowGraph dfg, Ship memoryShip) {
23         super(dfg);
24         this.ship = memoryShip;
25
26         // ugly hack
27         if (ship.getType().equals("Dvi")) {
28             new DockInPort("inPixelX", ship.getDock("inPixelX"), 0, new BitVector[] { null });
29             new DockInPort("inPixelY", ship.getDock("inPixelY"), 0, new BitVector[] { null });
30             new DockInPort("inPixelValue", ship.getDock("inPixelValue"), 0, new BitVector[] { null });
31         }
32
33         this.inCBD        = ship.getType().equals("Memory") ? new DockInPort("inCBD", ship.getDock("inCBD")) : null;
34         this.inDataWrite  = new DockInPort("inDataWrite", ship.getDock("inDataWrite"));
35         this.inAddrWrite  = new InPort("inAddrWrite") {
36                 public void recvToken(LoopFactory lf) { lf.recvToken(); }
37                 public void sendWord(LoopFactory lf) { lf.sendWord(ship.getDock("inAddrWrite").getDataDestination()); }
38                 public void build(CodeBag ctx) {
39                     LoopFactory lf = ctx.loopFactory(ship.getDock("inAddrWrite"), 0);
40                     lf.abortLoopIfTorpedoPresent();
41                     lf.recvWord();
42                     lf.deliver();
43                 }
44                 public int getTokensToAbsorb() { return outWrite.peer.getTokensToAbsorb(); }
45                 public int reset(CodeBag ctx, int phase, Destination ackDestination) {
46                     return DoneNode.doReset(ctx, phase, ship.getDock("inAddrWrite"), this, null, ackDestination, false);
47                 }
48             };
49         this.inAddrRead1  = new InPort("inAddrRead1") {
50                 public void recvToken(LoopFactory lf) { lf.recvToken(); }
51                 public void sendWord(LoopFactory lf) { lf.sendWord(ship.getDock("inAddrRead").getDataDestination(), new BitVector(1).set(0)); }
52                 public void build(CodeBag ctx) { }
53                 public int getTokensToAbsorb() { return outRead1.peer.getTokensToAbsorb(); }
54                 public int reset(CodeBag ctx, int phase, Destination ackDestination) {
55                     return DoneNode.doReset(ctx, phase, ship.getDock("inAddrRead"), this, null, ackDestination, false);
56                 }
57             };
58         this.inAddrRead2  = new InPort("inAddrRead2") {
59                 public void recvToken(LoopFactory lf) { lf.recvToken(); }
60                 public void sendWord(LoopFactory lf) { lf.sendWord(ship.getDock("inAddrRead").getDataDestination(), new BitVector(1).set(1)); }
61                 public void build(CodeBag ctx) { }
62                 public int getTokensToAbsorb() { return outRead2.peer.getTokensToAbsorb(); }
63                 public int reset(CodeBag ctx, int phase, Destination ackDestination) { return 0; }
64             };
65         this.outRead1 = new OutPort("outRead1") {
66                 public void sendToken(LoopFactory lf) { inAddrRead1.peer.sendToken(lf); }
67                 public void recvWord(LoopFactory lf) { lf.recvWord(); }
68                 public int getNumInitialTokens() { return Math.max(1,Node.CAPACITY/2); }
69                 public void build(CodeBag ctx) { }
70                 public int  reset(CodeBag ctx, int phase, Destination ackDestination) { return 0; }
71             };
72         this.outRead2 = new OutPort("outRead2") {
73                 public void sendToken(LoopFactory lf) { inAddrRead2.peer.sendToken(lf); }
74                 public void recvWord(LoopFactory lf) { lf.recvWord(); }
75                 public int getNumInitialTokens() { return Math.max(1,Node.CAPACITY/2); }
76                 public void build(CodeBag ctx) { }
77                 public int  reset(CodeBag ctx, int phase, Destination ackDestination) { return 0; }
78             };
79         this.outWrite = new DockOutPort("out", ship.getDock("out")) {
80                 public void sendToken(LoopFactory lf) { inAddrWrite.peer.sendToken(lf); }
81                 public void recvWord(LoopFactory lf) { lf.recvWord(); }
82                 public int getTokensToAbsorb() { return 0; }
83                 public int reset(CodeBag ctx, int phase, Destination ackDestination) {
84                     // ugly-ass hack
85                     if (phase!=0)
86                         return DoneNode.doReset(ctx, phase, dock, this, peer, ackDestination, true);
87                     return 0;
88                 }
89                 protected void build(CodeBag ctx, LoopFactory lf) {
90                     lf = lf.makeNext(0);
91                     lf.abortLoopIfTorpedoPresent();
92                     lf.collectWord();
93                         
94                     lf.setFlags(FlagFunction.ONE, FlagFunction.ZERO.add(FlagC));
95                     if (this.peer != null) {
96                         lf.setPredicate(Predicate.FlagB);
97                         lf.literal(77);
98                         lf.abortLoopIfTorpedoPresent();
99                         this.peer.sendWord(lf);
100                     }
101                         
102                     lf.setPredicate(Predicate.NotFlagB);
103                     lf.abortLoopIfTorpedoPresent();
104                     lf.recvToken();
105                     lf.setFlags(FlagFunction.ZERO.add(NotFlagC).add(FlagB), FlagFunction.ZERO.add(FlagC).add(FlagB));
106                     if (outRead1.peer != null) {
107                         lf.setPredicate(Predicate.NotFlagB);
108                         outRead1.peer.sendWord(lf);
109                     }
110                     if (outRead2.peer != null) {
111                         lf.setPredicate(Predicate.NotFlagA);
112                         outRead2.peer.sendWord(lf);
113                     }
114                     lf.setPredicate(null);
115                 }
116             };
117     }
118     public void build(CodeBag ctx) {
119         super.build(ctx);
120         LoopFactory lf;
121
122         lf = ctx.loopFactory(ship.getDock("inAddrRead"), 0);
123         lf.abortLoopIfTorpedoPresent();
124         lf.recvWord();
125         lf.setFlags(FlagFunction.ZERO.add(FlagC), FlagFunction.ZERO);
126         lf.setPredicate(Predicate.NotFlagA);
127         lf.sendToken(ship.getDock("out").getDataDestination(), new BitVector(1).set(0));
128         lf.setPredicate(Predicate.FlagA);
129         lf.sendToken(ship.getDock("out").getDataDestination(), new BitVector(1).set(1));
130         lf.setPredicate(null);
131         lf.deliver();
132     }
133
134
135
136     public static void clearMem(FleetProcess fp,
137                                 Ship memory,
138                                 ShipPool pool,
139                                 long offset,
140                                 long count) throws RuntimeException {
141
142         DataFlowGraph dfg = new DataFlowGraph(fp.getFleet(), pool);
143
144         MemoryNode mem = new MemoryNode(dfg, memory);
145         UnPunctuatorNode discard = new UnPunctuatorNode(dfg, true);
146         discard.count.connect(new OnceNode(dfg, (int)(count)).out);
147         DebugNode debug = new DebugNode(dfg);
148         DownCounterNode c1 = new DownCounterNode(dfg);
149         c1.start.connect(new OnceNode(dfg, count).out);
150         c1.incr.connect(new OnceNode(dfg, 1).out);
151         mem.inAddrWrite.connect(c1.out);
152         mem.inDataWrite.connect(new ForeverNode(dfg, 0).out);
153         mem.outWrite.connect(discard.val);
154         discard.out.connect(debug.in);
155
156         CodeBag ctx = new CodeBag(fp.getFleet());
157         dfg.build(ctx);
158         ctx.dispatch(fp, true);
159         System.out.println("waiting...");
160         fp.recvWord();
161         System.out.println("... done");
162
163         // FIXME: cleanup?
164     }
165
166     public static void main(String[] s) throws Exception {
167         Fleet fleet = new Fpga();
168         FleetProcess fp;
169         ShipPool pool = new ShipPool(fleet);
170         Ship mem1 = pool.allocateShip("Memory");
171         Ship mem2 = pool.allocateShip("Memory");
172         Ship mem3 = pool.allocateShip("Memory");
173
174         fp = fleet.run(new Instruction[0]);
175         clearMem(fp, mem1, new ShipPool(fleet), 0, 16 * 1024);
176         fp.terminate();
177
178         fp = fleet.run(new Instruction[0]);
179         clearMem(fp, mem2, new ShipPool(fleet), 0, 16 * 1024);
180         fp.terminate();
181
182         fp = fleet.run(new Instruction[0]);
183         clearMem(fp, mem3, new ShipPool(fleet), 0, 16 * 1024);
184         fp.terminate();
185     }
186
187
188 }