1 package edu.berkeley.fleet.fpga;
2 import edu.berkeley.fleet.api.*;
3 import edu.berkeley.fleet.two.*;
4 import edu.berkeley.fleet.*;
5 import java.lang.reflect.*;
6 import edu.berkeley.sbp.chr.*;
7 import edu.berkeley.sbp.misc.*;
8 import edu.berkeley.sbp.meta.*;
9 import edu.berkeley.sbp.util.*;
12 import static edu.berkeley.fleet.two.FleetTwoFleet.*;
13 import static edu.berkeley.fleet.fpga.verilog.Verilog.*;
14 import edu.berkeley.fleet.api.*;
15 import edu.berkeley.fleet.api.Dock;
16 import edu.berkeley.fleet.two.*;
20 /** the pump itself is a */
21 public class FpgaDock extends FleetTwoDock implements FabricElement {
23 private static final int INSTRUCTION_FIFO_SIZE = 8;
25 private FpgaDestination dataDestination;
26 private FpgaDestination instructionDestination;
28 private Module.InstantiatedModule instance;
30 public Module.InstantiatedModule getInstance() { return instance; }
32 public Destination getDataDestination() { return dataDestination; }
33 public Destination getInstructionDestination() { return instructionDestination; }
34 public int getInstructionFifoSize() { return INSTRUCTION_FIFO_SIZE; }
36 FpgaDock(FpgaShip ship, DockDescription bbd) {
38 this.instance = new Module.InstantiatedModule(((Fpga)ship.getFleet()).top, new DockModule(isInputDock()));
39 this.dataDestination = new FpgaDestination(this, this.instance.getInputPort("fabric_in"), false);
40 this.instructionDestination = new FpgaDestination(this, this.instance.getInputPort("instruction"), true);
41 Module.InstantiatedModule shipm = ship.getVerilogModule();
43 instance.getOutputPort("ship").connect(shipm.getInputPort(getName()));
45 shipm.getOutputPort(getName()).connect(instance.getInputPort("ship"));
50 // FabricElement methods //////////////////////////////////////////////////////////////////////////////
52 private FabricElement upstream;
53 public Module.Port getOutputPort() { throw new RuntimeException(); }
54 public Module.Port getInputPort() { throw new RuntimeException(); }
55 public FpgaPath getPath(FabricElement dest, BitVector signal) { return upstream.getPath((FabricElement)dest, signal); }
56 public FpgaPath getPath(Destination dest,BitVector signal) { return upstream.getPath((FabricElement)dest, signal); }
57 public void addInput(FabricElement in, Module.Port inPort) { throw new RuntimeException(); }
58 public void addOutput(FabricElement out, Module.Port outPort) {
60 instance.getOutputPort("fabric_out").connect((Module.SinkPort)outPort);
63 public static class DockModule extends Module {
65 public DockModule(boolean inbox) {
66 super(inbox ? "inbox" : "outbox");
67 Module fifo4 = new FifoModule(4);
68 Module fifo8 = new FifoModule(8);
70 Module ififo_m = new FifoModule(INSTRUCTION_FIFO_SIZE);
71 Module efifo_m = fifo4;
72 Module.SourcePort instruction = createInputPort("instruction", WIDTH_PACKET);
73 instruction.hasLatch = true;
75 Module.SourcePort fabric_in = createInputPort("fabric_in", WIDTH_PACKET);
76 Module.SinkPort fabric_out = createOutputPort("fabric_out", WIDTH_PACKET, "");
77 Module.InstantiatedModule dfifo = new Module.InstantiatedModule(this, fifo);
78 fabric_in.connect(dfifo.getInputPort("in"));
80 Module.SourcePort dfifo_out = dfifo.getOutputPort("out");
81 Module.SourcePort ship_out = null;
83 ship_out = createInputPort("ship", WIDTH_WORD);
84 ship_out.hasLatch = true;
87 Module.SinkPort ship_in = null;
89 ship_in = createOutputPort("ship", WIDTH_PACKET, "");
90 ship_in.hasLatch = true;
93 Module.Latch ondeck = new Latch("ondeck", WIDTH_WORD);
94 Module.Latch repeat_counter = new Latch("repeat_counter", SET_ILC_FROM_IMMEDIATE.valmaskwidth+1, 1);
95 Module.Latch loop_counter = new Latch("loop_counter", SET_OLC_FROM_IMMEDIATE.valmaskwidth, 1);
96 Module.Latch tapl = new Latch("tapl", SET_TAPL_FROM_IMMEDIATE.valmaskwidth);
97 Module.Latch flag_a = new Latch("flag_a", 1);
98 Module.Latch flag_b = new Latch("flag_b", 1);
99 Module.Latch flag_c = new Latch("flag_c", 1);
100 Module.StateWire ondeckFull = new StateWire("ondeck_full");
101 Module.StateWire newMayProceed = new StateWire("newmayproceed", true);
102 Module.StateWire doRepeat = new StateWire("dorepeat", false);
104 Module.StateWire isHatchOpen = new StateWire("hatch", true);
106 Module.SinkPort token_out = fabric_out;
107 Module.SourcePort token_in = dfifo_out;
108 Module.SinkPort data_out = inbox ? ship_in : fabric_out;
109 Module.SourcePort data_in = inbox ? dfifo_out : ship_out;
111 Module.InstantiatedModule ififo = new Module.InstantiatedModule(this, ififo_m);
112 Module.SinkPort ififo_in = ififo.getInputPort("in");
113 Module.SourcePort ififo_out = ififo.getOutputPort("out");
115 Module.InstantiatedModule efifo = new Module.InstantiatedModule(this, efifo_m);
116 Module.SinkPort efifo_in = efifo.getInputPort("in");
117 Module.SourcePort efifo_out = efifo.getOutputPort("out");
118 efifo_in.hasLatch = true;
120 addPreCrap("wire [(`DATAWIDTH-1):0] data_latch_output;");
121 addPreCrap("wire [(`DATAWIDTH-1):0] data_latch_input;");
122 addPreCrap("assign data_latch_output = " +
123 (inbox ? data_out.getName() : "`packet_data("+data_out.getName()+")")+";");
124 addPreCrap("assign data_latch_input = " +
125 (inbox ? "`packet_data("+data_in.getName()+")" : data_in.getName())+";");
126 Assignable data_latch = new SimpleAssignable(inbox ? data_out.getName() :
127 "`packet_data("+data_out.getName()+")");
128 String data_latch_input = "data_latch_input";
131 new Event(new Object[] { "loop_counter==0" },
132 new Action[] { isHatchOpen.doFill() });
135 new Event(new Object[] { instruction,
136 PACKET_TOKEN.verilogVal("instruction"),
141 new Action[] { instruction,
142 ondeckFull.doDrain(),
143 newMayProceed.doFill(),
144 new AssignAction(loop_counter, "0"),
145 new AssignAction(repeat_counter, "1"),
146 new AssignAction(new SimpleAssignable("`packet_token("+token_out.getName()+")"), "1"),
147 new AssignAction(new SimpleAssignable("`packet_dest("+token_out.getName()+")"), "tapl"),
149 isHatchOpen.doFill(),
151 // Non-Torpedo Arrival
152 new Event(new Object[] { instruction,
154 "!("+PACKET_TOKEN.verilogVal("instruction")+")"
159 new AssignAction(efifo_in, instruction)
163 new Event(new Object[] { efifo_out, TAIL.verilog("`packet_data("+efifo_out.getName()+")") },
164 new Action[] { efifo_out, isHatchOpen.doDrain() } );
166 new Event(new Object[] { efifo_out,
168 "!("+TAIL.verilog("`packet_data("+efifo_out.getName()+")")+")",
169 isHatchOpen.isFull() },
170 new Action[] { efifo_out, ififo_in, new AssignAction(ififo_in, "`packet_data("+efifo_out.getName()+")") } );
173 new Event(new Object[] { ififo_out,
174 ondeckFull.isEmpty(),
175 newMayProceed.isFull(),
177 new Action[] { ififo_out,
179 newMayProceed.doDrain(),
180 new AssignAction(ondeck, ififo_out)
185 new Event(new Object[] { doRepeat.isFull() },
186 new Action[] { doRepeat.doDrain(), ondeckFull.doFill(),
187 new AssignAction(repeat_counter,
188 "repeat_counter==`magic_standing_value?`magic_standing_value:(repeat_counter-1)")
193 new Object[] { ondeckFull.isFull(),
197 "(!`predicate_met(ondeck) || "+OS.verilog("ondeck")+" || !hatch)",
198 new ConditionalTrigger("(`predicate_met(ondeck) && `instruction_bit_datain(ondeck))", data_in),
199 new ConditionalTrigger("(`predicate_met(ondeck) && `instruction_bit_tokenin(ondeck))", token_in)
201 new Action[] { ondeckFull.doDrain(),
202 new ConditionalAction("`done_executing(ondeck)", newMayProceed.doFill()),
203 new ConditionalAction("`done_executing(ondeck) && `instruction_is_normal(ondeck)",
204 new AssignAction(repeat_counter, "1")),
205 new ConditionalAction("`should_requeue(ondeck) && `done_executing(ondeck)", ififo_in),
206 new ConditionalAction("`should_requeue(ondeck) && `done_executing(ondeck)", new AssignAction(ififo_in, ondeck)),
207 new ConditionalAction("!`done_executing(ondeck)", doRepeat.doFill()),
209 new ConditionalAction("`predicate_met(ondeck) && `instruction_is_load_data_to_loop(ondeck)",
210 new AssignAction(loop_counter, "data_latch_output")),
211 new ConditionalAction("`predicate_met(ondeck) && `instruction_is_load_immediate_to_loop(ondeck)",
212 new AssignAction(loop_counter, "`instruction_loop_count_immediate(ondeck)")),
213 new ConditionalAction("`predicate_met(ondeck) && `instruction_is_decr_loop(ondeck)",
214 new AssignAction(loop_counter, "loop_counter==0 ? 0 : (loop_counter-1)")),
216 new ConditionalAction("`predicate_met(ondeck) && `instruction_is_load_data_to_repeat(ondeck)",
217 new AssignAction(repeat_counter, "data_latch_output")),
218 new ConditionalAction("`predicate_met(ondeck) && `instruction_is_load_immediate_to_repeat(ondeck)",
219 new AssignAction(repeat_counter, "`instruction_repeat_count_immediate(ondeck)")),
220 new ConditionalAction("`predicate_met(ondeck) && `instruction_is_load_standing_to_repeat(ondeck)",
221 new AssignAction(repeat_counter, "`magic_standing_value")),
222 new ConditionalAction("`predicate_met(ondeck) &&"+SHIFT.verilog("ondeck"),
223 new AssignAction(data_latch,
224 "({ data_latch_output["+(WIDTH_WORD-1-19)+":0], 19'b0 } | "+
225 SHIFT.verilogVal("ondeck")+")")),
226 new ConditionalAction("`predicate_met(ondeck) && "+SET_IMMEDIATE.verilog("ondeck"),
227 new AssignAction(data_latch,
228 "{ {"+(WIDTH_WORD-FleetTwoFleet.DataLatch_WIDTH)+
229 "{"+SET_IMMEDIATE_EXTEND.verilogVal("ondeck")+"}}, "+
230 SET_IMMEDIATE.verilogVal("ondeck")+" }")),
231 new ConditionalAction("`predicate_met(ondeck) && `instruction_is_setflags(ondeck)",
232 new AssignAction(flag_a, "`new_flag_a(ondeck)")),
233 new ConditionalAction("`predicate_met(ondeck) && `instruction_is_setflags(ondeck)",
234 new AssignAction(flag_b, "`new_flag_b(ondeck)")),
236 ? new ConditionalAction("`predicate_met(ondeck) && "+
237 "(`instruction_bit_datain(ondeck) || `instruction_bit_tokenin(ondeck))",
238 new AssignAction(flag_c, PACKET_SIGNAL.verilogVal(dfifo_out.getName())))
239 : new ConditionalAction("`predicate_met(ondeck) && "+
240 "(!`instruction_bit_datain(ondeck) && `instruction_bit_tokenin(ondeck))",
241 new AssignAction(flag_c, PACKET_SIGNAL.verilogVal(dfifo_out.getName())))
242 /* FIXME: C-flag-from-ship */
244 new ConditionalAction("`predicate_met(ondeck) && `instruction_bit_datain(ondeck)", data_in),
245 new ConditionalAction("`predicate_met(ondeck) && `instruction_bit_dataout(ondeck)", data_out),
246 new ConditionalAction("`predicate_met(ondeck) && `instruction_bit_tokenin(ondeck)", token_in),
247 new ConditionalAction("`predicate_met(ondeck) && `instruction_bit_tokenout(ondeck)", token_out),
248 new ConditionalAction("`predicate_met(ondeck) && `instruction_bit_tokenout(ondeck)",
249 new AssignAction(new SimpleAssignable("`packet_token("+token_out.getName()+")"),
251 new ConditionalAction("`predicate_met(ondeck) && !`instruction_bit_tokenout(ondeck)",
252 new AssignAction(new SimpleAssignable("`packet_token("+token_out.getName()+")"),
254 new ConditionalAction("`predicate_met(ondeck) && `instruction_bit_latch(ondeck)",
255 new AssignAction(data_latch, data_latch_input)),
256 new ConditionalAction("`predicate_met(ondeck) && `instruction_path_from_data(ondeck)",
257 new AssignAction(new SimpleAssignable("`packet_signal_and_dest("+token_out.getName()+")"),
258 DISPATCH_PATH.verilogVal(data_latch_input))),
259 new ConditionalAction("`predicate_met(ondeck) && "+SET_TAPL_FROM_IMMEDIATE.verilog("ondeck"),
260 new AssignAction(tapl, SET_TAPL_FROM_IMMEDIATE.verilogVal("ondeck"))),
261 new ConditionalAction("`predicate_met(ondeck) && `instruction_path_from_immediate(ondeck)",
262 new AssignAction(new SimpleAssignable("`packet_signal_and_dest("+token_out.getName()+")"),
263 "`instruction_path_immediate(ondeck)")),
268 public void dump(PrintWriter pw, boolean fix) {
270 pw.println("`define packet_signal_and_dest(p) { "+PACKET_SIGNAL.verilogVal("p")+", "+PACKET_DEST.verilogVal("p")+" }");
271 pw.println("`define instruction_is_load_data_to_repeat(i) "+SET_ILC_FROM_DATA_LATCH.verilog("i"));
272 pw.println("`define instruction_is_load_data_to_loop(i) "+SET_OLC_FROM_DATA_LATCH.verilog("i"));
273 pw.println("`define instruction_is_load_immediate_to_repeat(i) "+SET_ILC_FROM_IMMEDIATE.verilog("i"));
274 pw.println("`define instruction_is_load_immediate_to_loop(i) "+SET_OLC_FROM_IMMEDIATE.verilog("i"));
275 pw.println("`define instruction_is_load_standing_to_repeat(i) "+SET_ILC_FROM_INFINITY.verilog("i"));
276 pw.println("`define instruction_repeat_count_immediate(i) "+SET_ILC_FROM_IMMEDIATE.verilogVal("i"));
277 pw.println("`define instruction_loop_count_immediate(i) "+SET_OLC_FROM_IMMEDIATE.verilogVal("i"));
279 pw.println("`define instruction_path_immediate(i) "+PATH_IMMEDIATE.verilogVal("i"));
280 pw.println("`define instruction_path_from_immediate(i) "+PATH_IMMEDIATE.verilog("i"));
281 pw.println("`define instruction_path_from_data(i) "+PATH_DATA.verilog("i"));
283 pw.println("`define instruction_is_tail(i) "+TAIL.verilog("i"));
284 pw.println("`define instruction_is_normal(i) "+MOVE.verilog("i"));
285 pw.println("`define instruction_is_setflags(i) "+SET_FLAGS.verilog("i"));
286 pw.println("`define instruction_is_set(i) "+SET.verilog("i"));
288 pw.println("`define instruction_is_decr_loop(i) "+SET_OLC_FROM_OLC_MINUS_ONE.verilog("i"));
290 pw.println("`define instruction_bit_tokenout(i) (`instruction_is_normal(i) && "+TO.verilog("i")+")");
291 pw.println("`define instruction_bit_dataout(i) (`instruction_is_normal(i) && "+DO.verilog("i")+")");
292 pw.println("`define instruction_bit_latch(i) (`instruction_is_normal(i) && "+DC.verilog("i")+")");
293 pw.println("`define instruction_bit_datain(i) (`instruction_is_normal(i) && "+DI.verilog("i")+")");
294 pw.println("`define instruction_bit_tokenin(i) (`instruction_is_normal(i) && "+TI.verilog("i")+")");
295 pw.println("`define should_requeue(i) (loop_counter > 0 && !("+OS.verilog("i")+"))");
296 pw.println("`define predicate_met(i) ("+
298 "!`instruction_is_normal(i) || repeat_counter>0"+
300 " " + P_A.verilog("i")+" ? flag_a "+
301 ":" + P_B.verilog("i")+" ? flag_b "+
302 ":" + P_C.verilog("i")+" ? flag_c "+
303 ":" + P_NOT_A.verilog("i")+" ? !flag_a "+
304 ":" + P_NOT_B.verilog("i")+" ? !flag_b "+
305 ":" + P_NOT_C.verilog("i")+" ? !flag_c "+
306 ":" + P_OLC.verilog("i")+" ? (loop_counter>0) "+
310 pw.println("`define new_flag(x) ("+
311 "( ((x >> 0) & 1) & !flag_c) |" +
312 "( ((x >> 1) & 1) & flag_c) |" +
313 "( ((x >> 2) & 1) & !flag_b) |" +
314 "( ((x >> 3) & 1) & flag_b) |" +
315 "( ((x >> 4) & 1) & !flag_a) |" +
316 "( ((x >> 5) & 1) & flag_a) | 0" +
318 pw.println("`define new_flag_a(i) `new_flag("+SET_FLAGS_A.verilogVal("i")+")");
319 pw.println("`define new_flag_b(i) `new_flag("+SET_FLAGS_B.verilogVal("i")+")");
320 pw.println("`define done_executing(i) (repeat_counter==0 || repeat_counter==1 || !`instruction_is_normal(i))");
322 pw.println("`define magic_standing_value (1<<"+SET_ILC_FROM_IMMEDIATE.valmaskwidth+")");