package edu.berkeley.fleet.fpga;
import edu.berkeley.fleet.api.*;
-import edu.berkeley.fleet.ies44.*;
+import edu.berkeley.fleet.two.*;
import edu.berkeley.fleet.*;
import java.lang.reflect.*;
import edu.berkeley.sbp.chr.*;
import edu.berkeley.sbp.util.*;
import java.util.*;
import java.io.*;
-import static edu.berkeley.fleet.ies44.InstructionEncoder.*;
-import static edu.berkeley.fleet.verilog.Verilog.*;
+import static edu.berkeley.fleet.two.FleetTwoFleet.*;
+import static edu.berkeley.fleet.fpga.verilog.Verilog.*;
import edu.berkeley.fleet.api.*;
-import static edu.berkeley.fleet.verilog.Verilog.*;
import edu.berkeley.fleet.api.Dock;
import edu.berkeley.fleet.two.*;
import java.util.*;
-
-/** the pump itself is a */
public class FpgaDock extends FleetTwoDock implements FabricElement {
- private static final int INSTRUCTION_FIFO_SIZE = 8;
+ //private static final int INSTRUCTION_FIFO_SIZE = 12;
+
+ // Marina has 12 latches in the ring, 9 of which are wagged (plus
+ // M1, OD, RQ), so max capacity is 11 instructions
+ static final int INSTRUCTION_FIFO_SIZE = 11;
+ static final int INSTRUCTION_WAGGED_STAGES = 8;
+
+ //private static final int DATA_FIFO_SIZE = 4;
+ static final int DATA_FIFO_SIZE = 8;
private FpgaDestination dataDestination;
private FpgaDestination instructionDestination;
public Module.InstantiatedModule getInstance() { return instance; }
+ private Fpga fpga;
+
public Destination getDataDestination() { return dataDestination; }
public Destination getInstructionDestination() { return instructionDestination; }
public int getInstructionFifoSize() { return INSTRUCTION_FIFO_SIZE; }
FpgaDock(FpgaShip ship, DockDescription bbd) {
super(ship, bbd);
+ this.fpga = (Fpga)ship.getFleet();
this.instance = new Module.InstantiatedModule(((Fpga)ship.getFleet()).top, new DockModule(isInputDock()));
this.dataDestination = new FpgaDestination(this, this.instance.getInputPort("fabric_in"), false);
this.instructionDestination = new FpgaDestination(this, this.instance.getInputPort("instruction"), true);
// FabricElement methods //////////////////////////////////////////////////////////////////////////////
private FabricElement upstream;
- public Module.Port getOutputPort() { throw new RuntimeException(); }
+ public Module.SourcePort getOutputPort() { throw new RuntimeException(); }
public Module.Port getInputPort() { throw new RuntimeException(); }
- public FpgaPath getPath(FabricElement dest, BitVector signal) { return upstream.getPath((FabricElement)dest, signal); }
- public FpgaPath getPath(Destination dest,BitVector signal) { return upstream.getPath((FabricElement)dest, signal); }
+ public Path getPath(Destination dest,BitVector signal) { return getPath((FpgaDestination)dest, signal); }
+ public FpgaPath getPath(FpgaDestination dest,BitVector signal) { return upstream.getPath(dest, signal); }
+ public int getPathLength(FpgaDestination dest) { return upstream.getPathLength(dest)-1; }
public void addInput(FabricElement in, Module.Port inPort) { throw new RuntimeException(); }
public void addOutput(FabricElement out, Module.Port outPort) {
this.upstream = out;
instance.getOutputPort("fabric_out").connect((Module.SinkPort)outPort);
}
- public static class DockModule extends Module {
+ public class TorpedoBranchModule extends Module {
+ public TorpedoBranchModule() {
+ super("torpedobranch");
+ Module.SourcePort in = createInputPort ("in", fpga.WIDTH_PACKET);
+ Module.SinkPort out = createOutputPort("out", fpga.getWordWidth()-fpga.DISPATCH_PATH.valmaskwidth);
+ Module.SinkPort torpedo = createOutputPort("torpedo", 0);
+ Module.StateWire busy = new StateWire("busy", false);
+
+ new Event(new Object[] { in, busy.isFull(), out },
+ new Action[] { in, busy.doDrain() });
+ new Event(new Object[] { in, busy.isEmpty(), out, torpedo, in.testMask(fpga.PACKET_IS_TOKEN) },
+ new Action[] { in, torpedo });
+ new Event(new Object[] { in, busy.isEmpty(), out, in.testMask(fpga.PACKET_IS_TOKEN).invert() },
+ new Action[] { busy.doFill(), out });
+
+ out.connectValue(in.getBits(fpga.PACKET_DATA));
+ }
+ }
+
+ public class RequeueModule extends Module {
+ public RequeueModule() {
+ super("requeue");
+ Module.SourcePort fabric_in = createInputPort ("fabric_in", fpga.getWordWidth()-fpga.DISPATCH_PATH.valmaskwidth);
+ Module.SourcePort ondeck_in = createInputPort ("ondeck_in", fpga.getWordWidth()-fpga.DISPATCH_PATH.valmaskwidth);
+ Module.SourcePort abort = createInputPort ("abort", 1);
+ Module.SinkPort out = createOutputPort("out", fpga.getWordWidth()-fpga.DISPATCH_PATH.valmaskwidth);
+
+ Module.StateWire circulating = new StateWire("circulating", false);
+ Module.StateWire doResetFabric = new StateWire("doResetFabric", false);
+ Module.StateWire doResetOndeck = new StateWire("doResetOndeck", false);
+
+ out.connectValue(new MuxValue(circulating.isEmpty(), fabric_in, ondeck_in));
+
+ // always: discard one-shot instructions
+ new Event(new Object[] { doResetFabric.isFull(), out },
+ new Action[] { doResetFabric.doDrain(), fabric_in });
+ new Event(new Object[] { doResetOndeck.isFull(), out },
+ new Action[] { doResetOndeck.doDrain(), ondeck_in });
+
+ // Updating->Circulating transition
+ new Event(new Object[] { doResetFabric.isEmpty(),
+ doResetOndeck.isEmpty(),
+ circulating.isEmpty(),
+ fabric_in,
+ fpga.TAIL.verilog(fabric_in.getName()),
+ ondeck_in,
+ fpga.HEAD.verilog(ondeck_in.getName()) },
+ new Action[] { circulating.doFill(),
+ fabric_in,
+ ondeck_in });
+
+ // Circulating->Updating transition
+ new Event(new Object[] { doResetFabric.isEmpty(),
+ doResetOndeck.isEmpty(),
+ circulating.isFull(),
+ ondeck_in,
+ abort.getVerilog() },
+ new Action[] { circulating.doDrain(),
+ ondeck_in });
+
+ // Updating
+ new Event(new Object[] { doResetFabric.isEmpty(),
+ doResetOndeck.isEmpty(),
+ circulating.isEmpty(),
+ fabric_in,
+ "!"+fpga.TAIL.verilog(fabric_in.getName()) },
+ new Action[] { doResetFabric.doFill(),
+ out });
+ new Event(new Object[] { doResetFabric.isEmpty(),
+ doResetOndeck.isEmpty(),
+ circulating.isEmpty(),
+ ondeck_in,
+ "!"+fpga.HEAD.verilog(ondeck_in.getName()) },
+ new Action[] { ondeck_in });
+
+ // Circulating
+ new Event(new Object[] { doResetFabric.isEmpty(),
+ doResetOndeck.isEmpty(),
+ circulating.isFull(),
+ ondeck_in,
+ "!"+abort.getVerilog() },
+ new Action[] { doResetOndeck.doFill(),
+ out });
+ }
+ }
+
+ public class DockModule extends Module {
public DockModule(boolean inbox) {
super(inbox ? "inbox" : "outbox");
- Module fifo4 = new FifoModule(4);
- Module fifo8 = new FifoModule(8);
- Module fifo = fifo8;
- Module ififo_m = new FifoModule(INSTRUCTION_FIFO_SIZE);
- Module efifo_m = fifo4;
- Module.SourcePort instruction = createInputPort("instruction", WIDTH_PACKET);
- instruction.hasLatch = true;
-
- Module.SourcePort fabric_in = createInputPort("fabric_in", WIDTH_PACKET);
- Module.SinkPort fabric_out = createOutputPort("fabric_out", WIDTH_PACKET, "");
- Module.InstantiatedModule dfifo = new Module.InstantiatedModule(this, fifo);
+
+ int dfifo_width = inbox ? fpga.getWordWidth()+1 : 1;
+
+ // FIXME: assumes fpga.DISPATCH_PATH is at top of word!!!
+ Module ififo_m_1 = new FifoModule(INSTRUCTION_FIFO_SIZE, fpga.getWordWidth()-fpga.DISPATCH_PATH.valmaskwidth);
+ //Module ififo_m_1 = new FifoModule(INSTRUCTION_FIFO_SIZE-INSTRUCTION_WAGGED_STAGES, fpga.getWordWidth()-fpga.DISPATCH_PATH.valmaskwidth);
+ //Module ififo_m_2 = new FifoModule(INSTRUCTION_WAGGED_STAGES, fpga.getWordWidth()-fpga.DISPATCH_PATH.valmaskwidth, true);
+
+ Module dfifo_m = new FifoModule(DATA_FIFO_SIZE, dfifo_width);
+
+ Module.SourcePort instruction = createInputPort("instruction", fpga.WIDTH_PACKET);
+ Module.SourcePort fabric_in = createInputPort("fabric_in", fpga.WIDTH_PACKET);
+
+ // FIXME: at inboxes, no need for a full set of latches
+ Module.SinkPort fabric_out = createOutputPort("fabric_out", fpga.WIDTH_PACKET);
+
+ Module.InstantiatedModule dfifo = new Module.InstantiatedModule(this, dfifo_m);
+
fabric_in.connect(dfifo.getInputPort("in"));
+ dfifo.getInputPort("in").connectValue(
+ !inbox
+ ? fabric_in.getBits(fpga.PACKET_SIGNAL)
+ : new CatValue(new Value[] {
+ fabric_in.getBits(fpga.PACKET_SIGNAL),
+ fabric_in.getBits(fpga.PACKET_DATA)
+ }));
- Module.SourcePort dfifo_out = dfifo.getOutputPort("out");
- Module.SourcePort ship_out = null;
- if (!inbox) {
- ship_out = createInputPort("ship", WIDTH_WORD);
- ship_out.hasLatch = true;
- }
-
- Module.SinkPort ship_in = null;
- if (inbox) {
- ship_in = createOutputPort("ship", WIDTH_PACKET, "");
- ship_in.hasLatch = true;
- }
-
- Module.Latch ondeck = new Latch("ondeck", WIDTH_WORD);
- Module.Latch repeat_counter = new Latch("repeat_counter", SET_ILC_FROM_IMMEDIATE.valmaskwidth+1, 1);
- Module.Latch loop_counter = new Latch("loop_counter", SET_OLC_FROM_IMMEDIATE.valmaskwidth, 1);
- Module.Latch tapl = new Latch("tapl", SET_TAPL_FROM_IMMEDIATE.valmaskwidth);
+ Module.SourcePort dfifo_out = dfifo.getOutputPort("out");
+ Module.SourcePort ship_out = !inbox ? createInputPort("ship", fpga.getWordWidth()+1) : null;
+ Module.SinkPort ship_in = inbox ? createOutputPort("ship", fpga.getWordWidth()+1) : null;
+
+ Module.Latch ilc = new Latch("ilc", fpga.SET_ILC_FROM_IMMEDIATE.valmaskwidth+1, 1);
+ Module.Latch olc = new Latch("olc", fpga.getWordWidth(), 1);
Module.Latch flag_a = new Latch("flag_a", 1);
Module.Latch flag_b = new Latch("flag_b", 1);
Module.Latch flag_c = new Latch("flag_c", 1);
- Module.StateWire ondeckFull = new StateWire("ondeck_full");
- Module.StateWire newMayProceed = new StateWire("newmayproceed", true);
- Module.StateWire doRepeat = new StateWire("dorepeat", false);
+ Module.Latch flag_d = new Latch("flag_d", 1);
- Module.StateWire isHatchOpen = new StateWire("hatch", true);
-
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 = new Module.InstantiatedModule(this, ififo_m);
- Module.SinkPort ififo_in = ififo.getInputPort("in");
- Module.SourcePort ififo_out = ififo.getOutputPort("out");
-
- Module.InstantiatedModule efifo = new Module.InstantiatedModule(this, efifo_m);
- Module.SinkPort efifo_in = efifo.getInputPort("in");
- Module.SourcePort efifo_out = efifo.getOutputPort("out");
- efifo_in.hasLatch = true;
-
- addPreCrap("wire [(`DATAWIDTH-1):0] data_latch_output;");
- addPreCrap("wire [(`DATAWIDTH-1):0] data_latch_input;");
- addPreCrap("assign data_latch_output = " +
- (inbox ? data_out.getName() : "`packet_data("+data_out.getName()+")")+";");
- addPreCrap("assign data_latch_input = " +
- (inbox ? "`packet_data("+data_in.getName()+")" : data_in.getName())+";");
- Assignable data_latch = new SimpleAssignable(inbox ? data_out.getName() :
- "`packet_data("+data_out.getName()+")");
- String data_latch_input = "data_latch_input";
-
- // Open the Hatch
- new Event(new Object[] { "loop_counter==0" },
- new Action[] { isHatchOpen.doFill() });
-
- // Torpedo Arrival
- new Event(new Object[] { instruction,
- PACKET_TOKEN.verilogVal("instruction"),
- ondeckFull.isFull(),
- token_out,
- I.verilog("ondeck"),
- },
- new Action[] { instruction,
- ondeckFull.doDrain(),
- newMayProceed.doFill(),
- new AssignAction(loop_counter, "0"),
- new AssignAction(repeat_counter, "1"),
- new AssignAction(new SimpleAssignable("`packet_token("+token_out.getName()+")"), "1"),
- new AssignAction(new SimpleAssignable("`packet_dest("+token_out.getName()+")"), "tapl"),
- token_out,
- isHatchOpen.doFill(),
- });
- // Non-Torpedo Arrival
- new Event(new Object[] { instruction,
- efifo_in,
- "!("+PACKET_TOKEN.verilogVal("instruction")+")"
+ Module.InstantiatedModule ififo_1 = new Module.InstantiatedModule(this, ififo_m_1);
+ //Module.InstantiatedModule ififo_2 = new Module.InstantiatedModule(this, ififo_m_2);
+ //ififo_1.getOutputPort("out").connect(ififo_2.getInputPort("in"));
+ Module.SinkPort ififo_in = ififo_1.getInputPort("in");
+ //Module.SourcePort ififo_out = ififo_2.getOutputPort("out");
+ Module.SourcePort ififo_out = ififo_1.getOutputPort("out");
+
+ Module.InstantiatedModule torpedo_branch = new Module.InstantiatedModule(this, new TorpedoBranchModule());
+ instruction.connect(torpedo_branch.getInputPort("in"));
+ Module.SourcePort efifo_out = torpedo_branch.getOutputPort("out");
+ Module.SourcePort torpedo_branch_torpedo = torpedo_branch.getOutputPort("torpedo");
+
+ Module.InstantiatedModule fanout_module = new Module.InstantiatedModule(this, new FanoutModule(fpga.getWordWidth()-fpga.DISPATCH_PATH.valmaskwidth));
+ Module.SinkPort fanout_module_in = fanout_module.getInputPort("in");
+ Module.SourcePort fanout_module_out0 = fanout_module.getOutputPort("out0");
+ Module.SourcePort fanout_module_out1 = fanout_module.getOutputPort("out1");
+
+ Module.InstantiatedModule requeue_module = new Module.InstantiatedModule(this, new RequeueModule());
+ Module.SinkPort requeue_fabric_in = requeue_module.getInputPort("fabric_in");
+ Module.SinkPort requeue_ondeck = requeue_module.getInputPort("ondeck_in");
+ Module.SinkPort requeue_abort = requeue_module.getInputPort("abort");
+ Module.SourcePort requeue_out = requeue_module.getOutputPort("out");
+
+ efifo_out.connect(requeue_fabric_in);
+ requeue_out.connect(ififo_in);
+ ififo_out.connect(fanout_module_in);
+ fanout_module_out0.connect(requeue_ondeck);
+ Module.SourcePort ondeck = fanout_module_out1;
+
+ WireValue decremented = new WireValue("decremented", Math.max(ilc.width,olc.width),
+ new SimpleValue("("+ondeck.testMask(fpga.SET_OLC_FROM_OLC_MINUS_ONE).getVerilogTrigger()+
+ " ? olc : ilc)-1"));
+ WireValue data_latch_output_p = new WireValue("data_latch_output",
+ inbox ? fpga.getWordWidth()+1 : fpga.getWordWidth(),
+ (inbox
+ ? new SimpleValue(data_out.getName())
+ : new SimpleValue(data_out.getBits(fpga.PACKET_DATA).getVerilog()))
+ );
+
+ Assignable data_latch = new SimpleAssignable(inbox ? data_out.getName() : data_out.getBits(fpga.PACKET_DATA).getVerilog());
+ Module.SourcePort data_latch_input = inbox ? data_in : data_in;
+
+ BitVector bv = new BitVector(fpga.SET_ILC_FROM_IMMEDIATE.valmaskwidth+1);
+ bv.set(fpga.SET_ILC_FROM_IMMEDIATE.valmaskwidth, true);
+ Value magic_standing_value = new ConstantValue(bv);
+
+ Trigger done_executing = new SimpleTrigger("((ilc==0) || (ilc==1) || !"+fpga.MOVE.verilog(ondeck.getName())+")");
+
+ String predicate_met =
+ "("+
+ "("+
+ "!"+fpga.MOVE.verilog(ondeck.getName())+" || (ilc!=0)"+
+ ") && ("+
+ "("+
+ fpga.P_ALWAYS.verilog(ondeck.getName())+
+ ") || ("+
+ fpga.P_OLC_ZERO.verilog(ondeck.getName())+"==flag_d"+
+ ")"+
+ ") && ("+
+ " " + fpga.P_A.verilog(ondeck.getName())+" ? flag_a"+
+ ":" + fpga.P_B.verilog(ondeck.getName())+" ? flag_b"+
+ ":" + fpga.P_NOT_A.verilog(ondeck.getName())+" ? !flag_a"+
+ ":" + fpga.P_NOT_B.verilog(ondeck.getName())+" ? !flag_b "+
+ ": 1"+
+ ")"+
+ ")";
+
+ requeue_abort.connectValue(new SimpleValue("("+predicate_met+") && "+fpga.ABORT.verilog(ondeck.getName())));
+
+ // Torpedo strikes
+ new Event(new Object[] {
+ ondeck,
+ data_out,
+ token_out,
+ predicate_met,
+ fpga.MOVE.verilog(ondeck.getName()),
+ "!"+fpga.NOT_INTERRUPTIBLE.verilog(ondeck.getName()),
+ torpedo_branch_torpedo
},
- new Action[] {
- efifo_in,
- instruction,
- new AssignAction(efifo_in, instruction)
+ new Object[] {
+ ondeck,
+ torpedo_branch_torpedo,
+ new AssignAction(olc, new ConstantValue(new BitVector(olc.width).set(0))),
+ new AssignAction(flag_d, new ConstantValue(new BitVector(1).set(1))),
+ new AssignAction(ilc, new ConstantValue(new BitVector(ilc.width).set(1)))
});
- // Tail
- new Event(new Object[] { efifo_out, TAIL.verilog("`packet_data("+efifo_out.getName()+")") },
- new Action[] { efifo_out, isHatchOpen.doDrain() } );
- // Enqueue
- new Event(new Object[] { efifo_out,
- ififo_in,
- "!("+TAIL.verilog("`packet_data("+efifo_out.getName()+")")+")",
- isHatchOpen.isFull() },
- new Action[] { efifo_out, ififo_in, new AssignAction(ififo_in, "`packet_data("+efifo_out.getName()+")") } );
-
- // New
- new Event(new Object[] { ififo_out,
- ondeckFull.isEmpty(),
- newMayProceed.isFull(),
- },
- new Action[] { ififo_out,
- ondeckFull.doFill(),
- newMayProceed.doDrain(),
- new AssignAction(ondeck, ififo_out)
- }
- );
-
- // RepeatExecute
- new Event(new Object[] { doRepeat.isFull() },
- new Action[] { doRepeat.doDrain(), ondeckFull.doFill(),
- new AssignAction(repeat_counter,
- "repeat_counter==`magic_standing_value?`magic_standing_value:(repeat_counter-1)")
+ // Predicate not met
+ new Event(new Object[] { ondeck, "!("+predicate_met+")" },
+ new Action[] { ondeck,
+ new ConditionalAction(ondeck.testMask(fpga.MOVE),
+ new AssignAction(ilc, new ConstantValue(new BitVector(ilc.width).set(1))))
});
- // Execute
- new Event(
- new Object[] { ondeckFull.isFull(),
+ new Event(new Object[] { ondeck,
data_out,
token_out,
- ififo_in,
- "(!`predicate_met(ondeck) || "+OS.verilog("ondeck")+" || !hatch)",
- new ConditionalTrigger("(`predicate_met(ondeck) && `instruction_bit_datain(ondeck))", data_in),
- new ConditionalTrigger("(`predicate_met(ondeck) && `instruction_bit_tokenin(ondeck))", token_in)
+ predicate_met,
+ "(!"+fpga.MOVE.verilog(ondeck.getName())+" || "+fpga.NOT_INTERRUPTIBLE.verilog(ondeck.getName())+" || !"+torpedo_branch_torpedo.isFull()+")",
+ new ConditionalTrigger(ondeck.testMask(fpga.DI), data_in),
+ new ConditionalTrigger(ondeck.testMask(fpga.TI), token_in)
},
- new Action[] { ondeckFull.doDrain(),
- new ConditionalAction("`done_executing(ondeck)", newMayProceed.doFill()),
- new ConditionalAction("`done_executing(ondeck) && `instruction_is_normal(ondeck)",
- new AssignAction(repeat_counter, "1")),
- new ConditionalAction("`should_requeue(ondeck) && `done_executing(ondeck)", ififo_in),
- new ConditionalAction("`should_requeue(ondeck) && `done_executing(ondeck)", new AssignAction(ififo_in, ondeck)),
- new ConditionalAction("!`done_executing(ondeck)", doRepeat.doFill()),
-
- new ConditionalAction("`predicate_met(ondeck) && `instruction_is_load_data_to_loop(ondeck)",
- new AssignAction(loop_counter, "data_latch_output")),
- new ConditionalAction("`predicate_met(ondeck) && `instruction_is_load_immediate_to_loop(ondeck)",
- new AssignAction(loop_counter, "`instruction_loop_count_immediate(ondeck)")),
- new ConditionalAction("`predicate_met(ondeck) && `instruction_is_decr_loop(ondeck)",
- new AssignAction(loop_counter, "loop_counter==0 ? 0 : (loop_counter-1)")),
-
- new ConditionalAction("`predicate_met(ondeck) && `instruction_is_load_data_to_repeat(ondeck)",
- new AssignAction(repeat_counter, "data_latch_output")),
- new ConditionalAction("`predicate_met(ondeck) && `instruction_is_load_immediate_to_repeat(ondeck)",
- new AssignAction(repeat_counter, "`instruction_repeat_count_immediate(ondeck)")),
- new ConditionalAction("`predicate_met(ondeck) && `instruction_is_load_standing_to_repeat(ondeck)",
- new AssignAction(repeat_counter, "`magic_standing_value")),
- new ConditionalAction("`predicate_met(ondeck) &&"+SHIFT.verilog("ondeck"),
- new AssignAction(data_latch,
- "({ data_latch_output["+(WIDTH_WORD-1-19)+":0], 19'b0 } | "+
- SHIFT.verilogVal("ondeck")+")")),
- new ConditionalAction("`predicate_met(ondeck) && "+SET_IMMEDIATE.verilog("ondeck"),
- new AssignAction(data_latch,
- "{ {"+(WIDTH_WORD-InstructionEncoder.DataLatch_WIDTH)+
- "{"+SET_IMMEDIATE_EXTEND.verilogVal("ondeck")+"}}, "+
- SET_IMMEDIATE.verilogVal("ondeck")+" }")),
- new ConditionalAction("`predicate_met(ondeck) && `instruction_is_setflags(ondeck)",
- new AssignAction(flag_a, "`new_flag_a(ondeck)")),
- new ConditionalAction("`predicate_met(ondeck) && `instruction_is_setflags(ondeck)",
- new AssignAction(flag_b, "`new_flag_b(ondeck)")),
- (inbox
- ? new ConditionalAction("`predicate_met(ondeck) && "+
- "(`instruction_bit_datain(ondeck) || `instruction_bit_tokenin(ondeck))",
- new AssignAction(flag_c, PACKET_SIGNAL.verilogVal(dfifo_out.getName())))
- : new ConditionalAction("`predicate_met(ondeck) && "+
- "(!`instruction_bit_datain(ondeck) && `instruction_bit_tokenin(ondeck))",
- new AssignAction(flag_c, PACKET_SIGNAL.verilogVal(dfifo_out.getName())))
- /* FIXME: C-flag-from-ship */
- ),
- new ConditionalAction("`predicate_met(ondeck) && `instruction_bit_datain(ondeck)", data_in),
- new ConditionalAction("`predicate_met(ondeck) && `instruction_bit_dataout(ondeck)", data_out),
- new ConditionalAction("`predicate_met(ondeck) && `instruction_bit_tokenin(ondeck)", token_in),
- new ConditionalAction("`predicate_met(ondeck) && `instruction_bit_tokenout(ondeck)", token_out),
- new ConditionalAction("`predicate_met(ondeck) && `instruction_bit_tokenout(ondeck)",
- new AssignAction(new SimpleAssignable("`packet_token("+token_out.getName()+")"),
- "1")),
- new ConditionalAction("`predicate_met(ondeck) && !`instruction_bit_tokenout(ondeck)",
- new AssignAction(new SimpleAssignable("`packet_token("+token_out.getName()+")"),
- "0")),
- new ConditionalAction("`predicate_met(ondeck) && `instruction_bit_latch(ondeck)",
- new AssignAction(data_latch, data_latch_input)),
- new ConditionalAction("`predicate_met(ondeck) && `instruction_path_from_data(ondeck)",
- new AssignAction(new SimpleAssignable("`packet_signal_and_dest("+token_out.getName()+")"),
- DISPATCH_PATH.verilogVal(data_latch_input))),
- new ConditionalAction("`predicate_met(ondeck) && "+SET_TAPL_FROM_IMMEDIATE.verilog("ondeck"),
- new AssignAction(tapl, SET_TAPL_FROM_IMMEDIATE.verilogVal("ondeck"))),
- new ConditionalAction("`predicate_met(ondeck) && `instruction_path_from_immediate(ondeck)",
- new AssignAction(new SimpleAssignable("`packet_signal_and_dest("+token_out.getName()+")"),
- "`instruction_path_immediate(ondeck)")),
+ new Action[] {
+ new ConditionalAction(new AndTrigger(done_executing, ondeck.testMask(fpga.MOVE)),
+ new AssignAction(ilc, new ConstantValue(new BitVector(ilc.width).set(1)))),
+ new ConditionalAction(done_executing, ondeck),
+ new ConditionalAction(done_executing.invert(),
+ new AssignAction(ilc, new MuxValue(new TestValue(ilc, TestValue.TestType.EQ, magic_standing_value),
+ magic_standing_value,
+ decremented.getBits(ilc.width-1,0)))),
+ new ConditionalAction(ondeck.testMask(fpga.SET_OLC_FROM_DATA_LATCH),
+ new AssignAction(olc, new SimpleValue("data_latch_output"))),
+ new ConditionalAction(ondeck.testMask(fpga.SET_OLC_FROM_IMMEDIATE),
+ new AssignAction(olc, ondeck.getBits(fpga.SET_OLC_FROM_IMMEDIATE))),
+ new ConditionalAction(ondeck.testMask(fpga.SET_OLC_FROM_OLC_MINUS_ONE),
+ new AssignAction(olc, new SimpleValue("olc==0 ? 0 : decremented"))),
+
+ new ConditionalAction(ondeck.testMask(fpga.SET_OLC_FROM_DATA_LATCH),
+ new AssignAction(flag_d, new SimpleValue("data_latch_output==0"))),
+ new ConditionalAction(ondeck.testMask(fpga.SET_OLC_FROM_IMMEDIATE),
+ new AssignAction(flag_d, new SimpleValue(ondeck.getBits(fpga.SET_OLC_FROM_IMMEDIATE).getVerilog()+"==0"))),
+ new ConditionalAction(ondeck.testMask(fpga.SET_OLC_FROM_OLC_MINUS_ONE),
+ new AssignAction(flag_d, new SimpleValue("(olc==0 || olc==1)"))),
+
+ new ConditionalAction(ondeck.testMask(fpga.SET_ILC_FROM_DATA_LATCH),
+ new AssignAction(ilc, new SimpleValue("data_latch_output"))),
+
+ new ConditionalAction(ondeck.testMask(fpga.SET_ILC_FROM_IMMEDIATE),
+ new AssignAction(ilc, ondeck.getBits(fpga.SET_ILC_FROM_IMMEDIATE))),
+ new ConditionalAction(ondeck.testMask(fpga.SET_ILC_FROM_INFINITY),
+ new AssignAction(ilc, magic_standing_value)),
+ new ConditionalAction(ondeck.testMask(fpga.SHIFT),
+ new AssignAction(data_latch,
+ new SimpleValue("{ data_latch_output["+(fpga.getWordWidth()-1-fpga.SHIFT.valmaskwidth)+":0], "+
+ ondeck.getBits(fpga.SHIFT).getVerilog()+"}"))),
+ new ConditionalAction(ondeck.testMask(fpga.SET_IMMEDIATE),
+ new AssignAction(data_latch,
+ new SimpleValue("{ {"+(fpga.getWordWidth()-fpga.DataLatch_WIDTH)+
+ "{"+ondeck.getBits(fpga.SET_IMMEDIATE_EXTEND).getVerilog()+"}}, "+
+ ondeck.getBits(fpga.SET_IMMEDIATE).getVerilog()+" }"))),
+ new ConditionalAction(ondeck.testMask(fpga.SET_FLAGS),
+ new AssignAction(flag_a, new_flag(ondeck.getBits(fpga.SET_FLAGS_A),flag_a,flag_b,flag_c))),
+ new ConditionalAction(ondeck.testMask(fpga.SET_FLAGS),
+ new AssignAction(flag_b, new_flag(ondeck.getBits(fpga.SET_FLAGS_B),flag_a,flag_b,flag_c))),
+ new ConditionalAction(ondeck.testMask(fpga.MOVE),
+ new AssignAction(flag_c,
+ inbox
+ ? dfifo_out.getBits(dfifo_width-1, dfifo_width-1)
+ : new MuxValue(ondeck.testMask(fpga.DC),
+ ship_out.getBits(fpga.getWordWidth(), fpga.getWordWidth()),
+ dfifo_out.getBits(dfifo_width-1, dfifo_width-1))
+ )),
+ new ConditionalAction(ondeck.testMask(fpga.DI), data_in),
+ new ConditionalAction(ondeck.testMask(fpga.DO), data_out),
+ new ConditionalAction(ondeck.testMask(fpga.FLUSH), data_out),
+ inbox
+ ? new AssignAction(new SimpleAssignable(data_out.getName()+"["+fpga.getWordWidth()+"]"),
+ new SimpleValue(fpga.FLUSH.verilog(ondeck.getName())+"?1:0"))
+ : null,
+ new ConditionalAction(ondeck.testMask(fpga.TI), token_in),
+ new ConditionalAction(ondeck.testMask(fpga.TO), token_out),
+ new ConditionalAction(ondeck.testMask(fpga.DC), new AssignAction(data_latch, data_latch_input)),
+ new AssignAction(token_out.getBits(fpga.PACKET_TOKEN),
+ new SimpleValue("("+fpga.TO.verilog(ondeck.getName())+")?1:0")),
+ new ConditionalAction(ondeck.testMask(fpga.PATH_DATA),
+ new AssignAction(new SimpleAssignable("{ "+token_out.getBits(fpga.PACKET_SIGNAL).getVerilog()+", "+
+ token_out.getBits(fpga.PACKET_DEST).getVerilog()+" }"),
+ data_latch_input.getBits(fpga.DISPATCH_PATH))),
+ new ConditionalAction(ondeck.testMask(fpga.PATH_IMMEDIATE),
+ new AssignAction(new SimpleAssignable("{ "+token_out.getBits(fpga.PACKET_SIGNAL).getVerilog()+", "+
+ token_out.getBits(fpga.PACKET_DEST).getVerilog()+" }"),
+ ondeck.getBits(fpga.PATH_IMMEDIATE)))
}
- );
+ );
}
- public void dump(PrintWriter pw, boolean fix) {
-
- pw.println("`define packet_signal_and_dest(p) { "+PACKET_SIGNAL.verilogVal("p")+", "+PACKET_DEST.verilogVal("p")+" }");
- pw.println("`define instruction_is_load_data_to_repeat(i) "+SET_ILC_FROM_DATA_LATCH.verilog("i"));
- pw.println("`define instruction_is_load_data_to_loop(i) "+SET_OLC_FROM_DATA_LATCH.verilog("i"));
- pw.println("`define instruction_is_load_immediate_to_repeat(i) "+SET_ILC_FROM_IMMEDIATE.verilog("i"));
- pw.println("`define instruction_is_load_immediate_to_loop(i) "+SET_OLC_FROM_IMMEDIATE.verilog("i"));
- pw.println("`define instruction_is_load_standing_to_repeat(i) "+SET_ILC_FROM_INFINITY.verilog("i"));
- pw.println("`define instruction_repeat_count_immediate(i) "+SET_ILC_FROM_IMMEDIATE.verilogVal("i"));
- pw.println("`define instruction_loop_count_immediate(i) "+SET_OLC_FROM_IMMEDIATE.verilogVal("i"));
-
- pw.println("`define instruction_path_immediate(i) "+PATH_IMMEDIATE.verilogVal("i"));
- pw.println("`define instruction_path_from_immediate(i) "+PATH_IMMEDIATE.verilog("i"));
- pw.println("`define instruction_path_from_data(i) "+PATH_DATA.verilog("i"));
-
- pw.println("`define instruction_is_tail(i) "+TAIL.verilog("i"));
- pw.println("`define instruction_is_normal(i) "+MOVE.verilog("i"));
- pw.println("`define instruction_is_setflags(i) "+SET_FLAGS.verilog("i"));
- pw.println("`define instruction_is_set(i) "+SET.verilog("i"));
-
- pw.println("`define instruction_is_decr_loop(i) "+SET_OLC_FROM_OLC_MINUS_ONE.verilog("i"));
-
- pw.println("`define instruction_bit_tokenout(i) (`instruction_is_normal(i) && "+TO.verilog("i")+")");
- pw.println("`define instruction_bit_dataout(i) (`instruction_is_normal(i) && "+DO.verilog("i")+")");
- pw.println("`define instruction_bit_latch(i) (`instruction_is_normal(i) && "+DC.verilog("i")+")");
- pw.println("`define instruction_bit_datain(i) (`instruction_is_normal(i) && "+DI.verilog("i")+")");
- pw.println("`define instruction_bit_tokenin(i) (`instruction_is_normal(i) && "+TI.verilog("i")+")");
- pw.println("`define should_requeue(i) (loop_counter > 0 && !("+OS.verilog("i")+"))");
- pw.println("`define predicate_met(i) ("+
- "("+
- "!`instruction_is_normal(i) || repeat_counter>0"+
- ") && ("+
- " " + P_A.verilog("i")+" ? flag_a "+
- ":" + P_B.verilog("i")+" ? flag_b "+
- ":" + P_C.verilog("i")+" ? flag_c "+
- ":" + P_NOT_A.verilog("i")+" ? !flag_a "+
- ":" + P_NOT_B.verilog("i")+" ? !flag_b "+
- ":" + P_NOT_C.verilog("i")+" ? !flag_c "+
- ":" + P_OLC.verilog("i")+" ? (loop_counter>0) "+
- ": 1"+
- ")"+
- ")");
- pw.println("`define new_flag(x) ("+
- "( ((x >> 0) & 1) & !flag_c) |" +
- "( ((x >> 1) & 1) & flag_c) |" +
- "( ((x >> 2) & 1) & !flag_b) |" +
- "( ((x >> 3) & 1) & flag_b) |" +
- "( ((x >> 4) & 1) & !flag_a) |" +
- "( ((x >> 5) & 1) & flag_a) | 0" +
- ")");
- pw.println("`define new_flag_a(i) `new_flag("+SET_FLAGS_A.verilogVal("i")+")");
- pw.println("`define new_flag_b(i) `new_flag("+SET_FLAGS_B.verilogVal("i")+")");
- pw.println("`define done_executing(i) (repeat_counter==0 || repeat_counter==1 || !`instruction_is_normal(i))");
-
- pw.println("`define magic_standing_value (1<<"+SET_ILC_FROM_IMMEDIATE.valmaskwidth+")");
-
- super.dump(pw,fix);
+ private Value new_flag(Value v, Value flag_a, Value flag_b, Value flag_c) {
+ Value[] vals = new Value[] {
+ new LogicValue(v.getBits(0,0), LogicValue.LogicType.AND, flag_c.invertBits()),
+ new LogicValue(v.getBits(1,1), LogicValue.LogicType.AND, flag_c),
+ new LogicValue(v.getBits(2,2), LogicValue.LogicType.AND, flag_b.invertBits()),
+ new LogicValue(v.getBits(3,3), LogicValue.LogicType.AND, flag_b),
+ new LogicValue(v.getBits(4,4), LogicValue.LogicType.AND, flag_a.invertBits()),
+ new LogicValue(v.getBits(5,5), LogicValue.LogicType.AND, flag_a),
+ };
+ Value ret = new ConstantValue(new BitVector(1).set(0));
+ for(int i=0; i<vals.length; i++)
+ ret = new LogicValue(ret, LogicValue.LogicType.OR, vals[i]);
+ return ret;
}
}
}
+