+ private static Module mkBox(String name, boolean inbox, String prefix, Module fifo) throws Exception {
+ Module box = new Module(name);
+ Module.SourcePort instr = box.createInputPort("instr", INSTRUCTION_WIDTH);
+ Module.SourcePort fabric_in = box.createInputPort("fabric_in", PACKET_WIDTH);
+ Module.SinkPort fabric_out = box.createOutputPort("fabric_out", PACKET_WIDTH, "");
+ Module.InstantiatedModule dfifo = box.new InstantiatedModule(fifo);
+ fabric_in.connect(dfifo.getInputPort("in"));
+
+ Module.SourcePort dfifo_out = dfifo.getOutputPort("out");
+ Module.SourcePort ship_out = null;
+ if (!inbox) {
+ ship_out = box.createInputPort("ship", WORD_WIDTH);
+ ship_out.hasLatch = true;
+ }
+
+ Module.SinkPort ship_in = null;
+ if (inbox) {
+ ship_in = box.createOutputPort("ship", PACKET_WIDTH, "");
+ ship_in.hasLatch = true;
+ }
+
+ Module.Latch ondeck = box.new Latch("ondeck", INSTRUCTION_WIDTH);
+ Module.Latch repcount = box.new Latch("repcount", COUNT_WIDTH);
+ Module.StateWire ondeckFull = box.new StateWire("ondeck_full");
+ Module.StateWire newMayProceed = box.new StateWire("newmayproceed", true);
+ Module.StateWire doRepeat = box.new StateWire("dorepeat", false);
+ Module.StateWire doRepeatKill = box.new StateWire("dorepeatkill", false);
+ Module.StateWire doKill = box.new StateWire("dokill", false);
+ Module.StateWire isClogged = box.new StateWire("clogged", false);
+
+ Module.SinkPort token_out = fabric_out;
+ Module.SourcePort token_in = dfifo_out;
+ Module.SinkPort data_out = inbox ? ship_in : fabric_out;
+ Module.SourcePort data_in = inbox ? dfifo_out : ship_out;
+
+ Module.InstantiatedModule ififo = box.new InstantiatedModule(fifo);
+ Module.SinkPort ififo_in = ififo.getInputPort("in");
+ Module.SourcePort ififo_out = ififo.getOutputPort("out");
+
+ Value instruction_count_ondeck = ondeck .getBits(1+DESTINATION_WIDTH+COUNT_WIDTH-1, 1+DESTINATION_WIDTH);
+ Value instruction_count_instr = instr .getBits(1+DESTINATION_WIDTH+COUNT_WIDTH-1, 1+DESTINATION_WIDTH);
+ Assignable instruction_count_ififo_in = ififo_in.getAssignableBits(1+DESTINATION_WIDTH+COUNT_WIDTH-1, 1+DESTINATION_WIDTH);
+
+ // Clog (must be first)
+ box.new Event(
+ new Object[] { ififo_out, newMayProceed.isFull(), "`instruction_is_clog("+ififo_out.getName()+")" },
+ new Action[] { ififo_out, isClogged.doFill(), newMayProceed.doDrain() }
+ );
+
+ // UnClog
+ box.new Event(
+ new Object[] { instr, isClogged.isFull(), "`instruction_is_unclog(instr)" },
+ new Action[] { instr, isClogged.doDrain(), newMayProceed.doFill() }
+ );
+
+ // First Kill
+ box.new Event(
+ new Object[] { instr, ififo_out,
+ "`instruction_is_kill(instr)",
+ "!`instruction_is_unclog(instr)",
+ newMayProceed.isFull() },
+ new Action[] { instr, ififo_out,
+ new ConditionalAction("`instruction_count(instr)!=0", new AssignAction(repcount, instruction_count_instr+"-1")),
+ new ConditionalAction("`instruction_count(instr)!=0", doRepeatKill.doFill()),
+ new ConditionalAction("`instruction_count(instr)!=0", newMayProceed.doDrain()),
+ new ConditionalAction("`instruction_count(instr)==0", newMayProceed.doFill())
+ });
+
+ // Kill
+ box.new Event(
+ new Object[] { doKill.isFull() },
+ new Action[] { doKill.doDrain(),
+ new ConditionalAction("`instruction_count(instr)!=0", new AssignAction(repcount, instruction_count_instr+"-1")),
+ new ConditionalAction("`instruction_count(instr)!=0", doRepeatKill.doFill()),
+ new ConditionalAction("`instruction_count(instr)==0", newMayProceed.doFill())
+ });
+
+ // RepKill
+ box.new Event(
+ new Object[] { doRepeatKill.isFull(), ififo_out },
+ new Action[] { doRepeatKill.doDrain(), ififo_out, doKill.doFill(),
+ new AssignAction(instruction_count_ondeck, repcount) }
+ );
+
+ // Enqueue
+ box.new Event(
+ new Object[] { instr, ififo_in, "!`instruction_is_kill(instr)" },
+ new Action[] { instr, ififo_in, new AssignAction(ififo_in, instr) }
+ );
+
+ // New
+ box.new Event(
+ new Object[] { ififo_out, ondeckFull.isEmpty(), newMayProceed.isFull() },
+ new Action[] { ififo_out, ondeckFull.doFill(), newMayProceed.doDrain(),
+ new AssignAction(ondeck, ififo_out) }
+ );
+
+ // RepeatExecute
+ box.new Event(
+ new Object[] { doRepeat.isFull() },
+ new Action[] { doRepeat.doDrain(),
+ ondeckFull.doFill(),
+ new AssignAction(instruction_count_ondeck, repcount) }
+ );
+
+ Assignable data_latch = new SimpleAssignable(inbox ? data_out.getName() : "`packet_data("+data_out.getName()+")");
+ String data_latch_input = inbox ? "`packet_data("+data_in.getName()+")" : data_in.getName();
+ box.new Event(
+ new Object[] { ondeckFull.isFull(),
+ data_out,
+ token_out,
+ ififo_in,
+ new ConditionalTrigger("`instruction_bit_datain(ondeck)", data_in),
+ new ConditionalTrigger("`instruction_bit_tokenin(ondeck)", token_in)
+ },
+ new Action[] { new SimpleAction("ondeck_full<=0;"),
+ new ConditionalAction("`instruction_count(ondeck)==1 || `instruction_bit_recycle(ondeck)", newMayProceed.doFill()),
+ new ConditionalAction("`instruction_bit_recycle(ondeck) && `instruction_count(ondeck)!=1",
+ new AssignAction(ififo_in, ondeck)),
+ new ConditionalAction("`instruction_bit_recycle(ondeck) && `instruction_count(ondeck)!=1 && `instruction_count(ondeck)==0",
+ new AssignAction(instruction_count_ififo_in, "0")),
+ new ConditionalAction("`instruction_bit_recycle(ondeck) && `instruction_count(ondeck)!=1 && `instruction_count(ondeck)!=0",
+ new AssignAction(instruction_count_ififo_in, instruction_count_ondeck+"-1")),
+ new ConditionalAction("`instruction_bit_recycle(ondeck) && `instruction_count(ondeck)!=1", ififo_in),
+ new ConditionalAction("!`instruction_bit_recycle(ondeck) && `instruction_count(ondeck)!=1", doRepeat.doFill()),
+ new ConditionalAction("`instruction_count(ondeck)==0", new AssignAction(repcount, "0")),
+ new ConditionalAction("`instruction_count(ondeck)!=0", new AssignAction(repcount, instruction_count_ondeck+"-1")),
+ new ConditionalAction("`instruction_bit_datain(ondeck)", data_in),
+ new ConditionalAction("`instruction_bit_dataout(ondeck)", data_out),
+ new ConditionalAction("`instruction_bit_tokenin(ondeck)", token_in),
+ new ConditionalAction("`instruction_bit_tokenout(ondeck)", token_out),
+ new ConditionalAction("`instruction_bit_latch(ondeck)", new AssignAction(data_latch, data_latch_input)),
+ new ConditionalAction("`instruction_bit_tokenout(ondeck)",
+ new AssignAction(new SimpleAssignable("`packet_dest("+token_out.getName()+")"),
+ "`instruction_bit_dest(ondeck)")),
+ new ConditionalAction("`instruction_bit_dataout(ondeck)",
+ inbox ? new SimpleAction("")
+ : new AssignAction(new SimpleAssignable("`packet_dest("+data_out.getName()+")"),
+ "`instruction_bit_dest(ondeck)"))
+ }
+ );
+
+ PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(prefix+"/"+name+".v")));
+ box.dump(pw);
+ pw.flush();
+ return box;
+ }
+