1 package edu.berkeley.fleet.dataflow;
3 import edu.berkeley.fleet.loops.*;
4 import java.util.concurrent.Semaphore;
7 import edu.berkeley.fleet.two.*;
8 import edu.berkeley.fleet.api.*;
9 import edu.berkeley.fleet.fpga.*;
10 import edu.berkeley.fleet.api.Instruction.*;
11 import edu.berkeley.fleet.api.Instruction.Set;
12 import edu.berkeley.fleet.api.Instruction.Set.*;
13 import static edu.berkeley.fleet.api.Predicate.*;
14 import static edu.berkeley.fleet.util.BitManipulations.*;
18 public static int CAPACITY = 4;
20 public final DataFlowGraph dfg;
21 public Node(DataFlowGraph dfg) {
26 private HashMap<String,Port> ports = new HashMap<String,Port>();
27 public void build(CodeBag ctx) { for(Port p : ports.values()) p.build(ctx); }
28 public int reset(CodeBag ctx, int phase, Destination ackDestination) {
30 for(Port p : ports.values()) ret += p.reset(ctx, phase, ackDestination);
34 public abstract class Port {
35 public final String name;
36 public Port(String name) {
38 if (Node.this.ports.get(name)!=null) throw new RuntimeException();
39 Node.this.ports.put(name,this);
41 public abstract void build(CodeBag ctx);
42 public abstract int reset(CodeBag ctx, int phase, Destination ackDestination);
43 public String toString() { return Node.this+"."+name; }
46 public abstract class InPort extends Port {
48 public InPort(String name) { super(name); }
49 public void connect(OutPort peer) {
54 public void connectOnce(long val) { connect(new OnceNode(dfg, val).out); }
55 public void connectForever(long val) { connect(new ForeverNode(dfg, val).out); }
57 public void setPeer(OutPort peer) {
58 if (this.peer!=null) throw new RuntimeException("cannot call setPeer() twice");
62 /** this port's peer (an OutPort) invokes this to have "recvToken" or equivalent inserted */
63 public abstract void recvToken(LoopFactory loopfactory_at_output_dock);
64 /** this port's peer (an OutPort) invokes this to have "sendWord" or equivalent inserted */
65 public abstract void sendWord(LoopFactory loopfactory_at_output_dock);
67 public int getTokensToAbsorb() { return 0; }
68 public int getMaxInFlight() { return 0; }
71 public abstract class OutPort extends Port {
73 public OutPort(String name) { super(name); }
74 public void connect(InPort peer) {
78 public void setPeer(InPort peer) {
79 if (this.peer!=null) throw new RuntimeException("cannot call setPeer() twice");
83 public int getNumInitialTokens() {
84 return peer.getMaxInFlight();
87 /** this port's peer (an InPort) invokes this to have "sendToken" or equivalent inserted */
88 public abstract void sendToken(LoopFactory loopfactory_at_input_dock);
89 /** this port's peer (an InPort) invokes this to have "recvWord" or equivalent inserted */
90 public abstract void recvWord(LoopFactory loopfactory_at_input_dock);
92 public int getTokensToAbsorb() {
93 if (peer==null) return 0;
94 return peer.getTokensToAbsorb();
98 public final class DockInPort extends InPort {
102 public boolean sticky = false;
103 public DockInPort(String name, Dock dock) { this(name, dock, 0); }
104 public DockInPort(String name, Dock dock, String constant) {
105 this(name, dock, 0, new BitVector[] { dock.getConstant(constant) }); }
106 public DockInPort(String name, Dock dock, int count) { this(name, dock, count, new BitVector[] { null }); }
107 public DockInPort(String name, Dock dock, int count, BitVector[] pattern) {
111 this.pattern = pattern;
113 public void recvToken(LoopFactory lf) { lf.recvToken(); }
114 public void sendWord(LoopFactory lf) { lf.sendWord(dock.getDataDestination()); }
115 public void build(CodeBag ctx) { build(ctx, ctx.loopFactory(dock, 1)); }
117 // this is the input dock's upper limit on how many data items
118 // may be in flight; the output dock to which it is connected
120 public int getMaxInFlight() { return CAPACITY; }
122 public int getTokensToAbsorb() { return sticky ? 0 : peer==null ? 0 : peer.getNumInitialTokens(); }
123 private boolean peerUsed() {
124 if (sticky) return false;
125 if (peer==null) return false;
126 for(int i=0; i<pattern.length; i++) if (pattern[i]==null) return true;
129 public int reset(CodeBag ctx, int phase, Destination ackDestination) {
130 return DoneNode.doReset(ctx, phase, dock, this, peer, ackDestination, peerUsed());
132 protected void build(CodeBag ctx, LoopFactory lf) {
135 if (count != 0) throw new RuntimeException("expected count==0, but count=="+count);
136 lf = lf.makeNext(1, true);
141 if (count != 0) throw new RuntimeException("expected count==0, but count=="+count);
142 lf = lf.makeNext(1, true);
143 lf.setFlags(FlagFunction.ZERO, FlagFunction.ZERO);
147 int inflight = (count != 0 && count < peer.getNumInitialTokens()) ? count : peer.getNumInitialTokens();
148 for(int i=0; i<inflight; i++) peer.sendToken(lf);
151 lf = lf.makeNext(count, true);
155 lf.setPredicate(Predicate.NotFlagB);
157 lf.setPredicate(null);
158 lf.setFlags(FlagFunction.ZERO, FlagFunction.ONE);
160 for(int i=0; i<pattern.length; i++) {
161 if (pattern[i]==null) {
163 lf.abortLoopIfTorpedoPresent();
168 lf.interruptibleNop();
171 lf.literal(pattern[i]);
172 lf.abortLoopIfTorpedoPresent();
178 // "torpedoable nop" to keep the dock in a receptive state
179 lf.abortLoopIfTorpedoPresent();
183 public BitVector getConstant(String constantName) {
184 return dock.getConstant(constantName);
188 public /*final*/ class DockOutPort extends OutPort {
189 public final Dock dock;
190 public final int count;
191 public DockOutPort(String name, Dock dock) { this(name, dock, 0); }
192 public DockOutPort(String name, Dock dock, int count) { super(name); this.dock = dock; this.count = count; }
193 public void sendToken(LoopFactory lf) { lf.sendToken(dock.getDataDestination()); }
194 public void recvWord(LoopFactory lf) { lf.recvWord(); }
195 public void build(CodeBag ctx) { build(ctx, ctx.loopFactory(dock, 1)); }
196 protected void build(CodeBag ctx, LoopFactory lf) {
197 if (peer==null) return;
198 lf = lf.makeNext(count);
199 lf.abortLoopIfTorpedoPresent();
204 public int reset(CodeBag ctx, int phase, Destination ackDestination) {
205 return DoneNode.doReset(ctx, phase, dock, this, peer, ackDestination, true);
209 BitVector bv(long l) { return new BitVector(dfg.fleet.getWordWidth()).set(l); }
210 BitVector[] bv(long[] l) {
211 BitVector[] ret = new BitVector[l.length];
212 for(int i=0; i<ret.length; i++) ret[i] = bv(l[i]);