public Instruction(Pump pump) { this.pump = pump; }
public String toString() { return pump+": "; }
- public static abstract class CountingInstruction extends Instruction {
- public final int count;
- public CountingInstruction(Pump pump, int count) {
- super(pump);
- this.count = count;
- }
- public boolean isStanding() { return count==0; }
- public abstract boolean isRequeueing();
- public String toString() { return super.toString()+(count==1?"":(isRequeueing()?("("+(count==0?"*":(count+""))+")"):("["+(count==0?"*":(count+""))+"]")))+" "; }
+ public boolean isLooping() { return false; }
+ public boolean isRepeating() { return false; }
+ public boolean isStanding() { return false; }
+ public boolean isSK() { return false; }
+ public boolean isDL() { return false; }
+
+ public static class Clog extends Instruction {
+ public Clog(Pump pump) { super(pump); }
+ public String toString() { return super.toString() + "clog;"; }
}
public static class UnClog extends Instruction {
public Massacre(Pump pump) { super(pump); }
}
- public static class Clog extends Executable {
- public Clog(Pump pump) { super(pump, 1); }
- public String toString() { return super.toString() + "clog;"; }
- public Instruction.Executable decrementCount() { return null; }
- public boolean isRequeueing() { return false; }
- }
-
- public static class Kill extends CountingInstruction {
- public Kill(Pump pump, int count) { super(pump, count); }
- public boolean isRequeueing() { return false; }
- public String toString() { return super.toString() + "kill;"; }
- }
-
- public static abstract class Executable extends CountingInstruction {
- public Executable(Pump pump, int count) { super(pump, count); }
- public abstract Instruction.Executable decrementCount();
+ public static class Kill extends Instruction {
+ public final int count;
+ public Kill(Pump pump, int count) { super(pump); this.count = count; }
+ public String toString() { return super.toString() + "kill"+(count==1?"":(" "+count))+";"; }
}
- public static class DecrLoop extends Executable {
- public DecrLoop(Pump pump) { super(pump, 1); }
- public Instruction.Executable decrementCount() { return null; }
- public boolean isRequeueing() { return false; }
+ public static class DecrLoop extends Instruction {
+ public DecrLoop(Pump pump) { super(pump); }
+ public boolean isDL() { return true; }
}
- public static class Counter extends Executable {
+ public static class Counter extends Instruction {
public static final int DATA_LATCH = -1;
public static final int REPEAT_COUNTER = -2;
public static final int LOOP_COUNTER = -3;
public final int source;
public final int dest;
- public Instruction.Executable decrementCount() { return null; }
- public boolean isRequeueing() { return false; }
public Counter(Pump pump, int source, int dest) {
- super(pump, 1);
+ super(pump);
this.source = source;
this.dest = dest;
}
ret.append(";");
return ret.toString();
}
+ public boolean isLooping() { return true; }
}
- public static class Move extends Executable {
+ public static class Move extends Instruction {
public final Destination dest;
public final boolean tokenIn;
public final boolean tokenOut;
public final boolean requeue;
public final boolean ignoreUntilLast;
-
- public boolean isRequeueing() { return requeue; }
+ public final boolean standing;
/** count=0 denotes a standing move */
public Move(Pump pump,
boolean tokenOut,
boolean requeue,
boolean ignoreUntilLast) {
- super(pump, count);
+ super(pump);
this.dest = dest;
this.tokenIn = tokenIn;
this.dataIn = dataIn;
this.tokenOut = tokenOut;
this.requeue = requeue;
this.ignoreUntilLast = ignoreUntilLast;
- if (count < 0)
- throw new RuntimeException("count field of an instruction must be >=0");
+ this.standing = count==0;
if (pump.isInbox() && tokenIn && dataIn)
throw new RuntimeException("cannot have both \"wait\" and \"take\"/\"recieve\" on an inbox: " + this);
if (pump.isOutbox() && tokenOut && dataOut)
throw new RuntimeException("cannot have latch bit set without dataIn bit: " + this);
}
- public Instruction.Executable decrementCount() {
- if (count==1) return null;
- return new Move(pump, dest, count==0 ? 0 : count-1,
- tokenIn, dataIn, latch, dataOutDest, dataOut, tokenOut, requeue, ignoreUntilLast);
- }
-
public String toString() {
// FIXME
String ret = super.toString();
return ret;
}
+ public boolean isLooping() { return true; }
+ public boolean isRepeating() { return true; }
+ public boolean isStanding() { return standing; }
}
- public static class LocalLiteral extends Executable {
+ /*
+ public static class FullLiteral extends Executable {
public final long literal;
- public final boolean high;
public boolean isRequeueing() { return true; }
- public LocalLiteral(Pump pump, long literal, int count, boolean high) {
- super(pump, count);
+ public HalfLiteral(Pump pump, long literal) {
+ super(pump, 1);
this.literal = literal;
- this.high = high;
}
public Instruction.Executable decrementCount() {
if (count==1) return null;
- return new LocalLiteral(pump, literal, count-1, high);
+ return new FullLiteral(pump, literal, count-1, high);
+ }
+ }
+ */
+
+ public static class HalfLiteral extends Instruction {
+ public final long literal;
+ public final boolean high;
+ public boolean isRequeueing() { return true; }
+ public HalfLiteral(Pump pump, long literal, int count, boolean high) {
+ super(pump);
+ this.literal = literal;
+ this.high = high;
}
+ public boolean isLooping() { return true; }
}
public static class CodeBagDescriptor extends Instruction {
} else if ("forever".equals(tt.child(1).head())) {
count = 0;
}
- cb.add(new Instruction.LocalLiteral(pump, getField(36, 19, literal), count, true));
- cb.add(new Instruction.LocalLiteral(pump, getField(18, 0, literal), count, false));
+ cb.add(new Instruction.HalfLiteral(pump, getField(36, 19, literal), count, true));
+ cb.add(new Instruction.HalfLiteral(pump, getField(18, 0, literal), count, false));
continue;
}
Tree ttx = null;
else if ("discard".equals(ttt.head())) { dataIn = true; latch = false; }
else if ("take".equals(ttt.head())) { dataIn = true; latch = true; }
else if ("recieve".equals(ttt.head())) { dataIn = true; latch = true; }
- else if ("send".equals(ttt.head())) { dataOutDest = true; }
+ else if ("send".equals(ttt.head())) { dataOutDest = true; dataOut = true; }
else if ("sendto".equals(ttt.head())) { dataOut = true; dest = portReference(ttt.child(0)); }
else if ("deliver".equals(ttt.head())) { dataOut = true; }
else if ("notify".equals(ttt.head())) { tokenOut = true; dest = portReference(ttt.child(0)); }
createShip("Memory", "memory2"); // need this to avoid a bug
createShip("Fifo", "fifo1");
createShip("Fifo", "fifo2");
+ createShip("Alu2", "alu2a");
+ createShip("BitFifo", "bitfifo");
+ // above is the minimal ship set needed to run the regression suite, excluding "ships" tests
+ /*
createShip("Fifo", "fifo3");
createShip("Alu1", "alu1");
- createShip("Alu2", "alu2a");
createShip("Lut3", "lut3");
createShip("Choice", "Choice");
createShip("Stack", "Stack");
createShip("Alu3", "alu3");
- createShip("BitFifo", "bitfifo");
+ */
+ // above is the minimal ship set needed to run the regression suite, including "ships" tests
- // above is the minimal ship set needed to run the regression suite
- // below are extra bonush ships
+ // below are extra bonus ships
/*
createShip("Alu2", "alu2b");
createShip("Alu2", "alu2c");
public class Generator {
- public static final int WIDTH_PACKET = WIDTH_WORD + WIDTH_DEST_ADDR;
+ public static final int WIDTH_PACKET = WIDTH_WORD + WIDTH_ADDR;
public static class SimpleValue implements Value {
private final String s;
public Assignable getAssignableBits(int high, int low) { return new SimpleValue(getVerilogName(), high, low); }
public void dump(PrintWriter pw) {
pw.println(" reg ["+(width-1)+":0] "+name+";");
- //pw.println(" initial "+name+"="+(initiallyFull?"1":"0")+";");
+ pw.println(" initial "+name+"=0;");
}
}
}
}
- public void dump(PrintWriter pw) {
+ public void dump(PrintWriter pw, boolean fix) {
pw.println("`include \"macros.v\"");
pw.println("module "+name+"(clk");
for(String name : portorder) {
}
}
- for(Event a : events) a.dump(pw);
+ for(Event a : events) a.dump(pw, fix);
pw.println(" begin end");
pw.println("end");
if (triggers[i] instanceof Port)
((Port)triggers[i]).hasLatch = true;
}
- public void dump(PrintWriter pw) {
+ public void dump(PrintWriter pw, boolean fix) {
pw.print("if (1");
for(Object o : triggers) {
if (o instanceof Trigger) pw.print(((Trigger)o).getVerilogTrigger());
}
pw.println(") begin ");
for(Object a : actions) pw.println(((Action)a).getVerilogAction());
- pw.println("end else ");
+ if (fix) pw.println("end /*else*/ ");
+ else pw.println("end else ");
}
}
}
pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(prefix+"/bitfields.v")));
pw.println("`define DATAWIDTH "+WIDTH_WORD);
pw.println("`define CODEBAG_SIZE_BITS "+WIDTH_CODEBAG_SIZE);
- pw.println("`define PUMP_ADDRESS_BITS "+WIDTH_PUMP_ADDR);
- pw.println("`define DESTINATION_ADDRESS_BITS "+WIDTH_DEST_ADDR);
+ pw.println("`define PUMP_ADDRESS_BITS "+WIDTH_ADDR);
+ pw.println("`define DESTINATION_ADDRESS_BITS "+WIDTH_ADDR);
+ /*
pw.println("`define COUNT_BITS "+WIDTH_COUNT);
pw.println("`define COUNT_WIDTH "+WIDTH_COUNT);
+ */
pw.println("`define PACKET_WIDTH (`DATAWIDTH + `DESTINATION_ADDRESS_BITS)");
pw.println("`define INSTRUCTION_WIDTH "+WIDTH_WORD);
pw.println("`define packet_data(p) p[(`DESTINATION_ADDRESS_BITS+`DATAWIDTH-1):(`DESTINATION_ADDRESS_BITS)]");
pw.println("`define packet_dest(p) p[(`DESTINATION_ADDRESS_BITS-1):0]");
pw.println("`define instruction_data(p) p[(`DATAWIDTH-1):0]");
- pw.println("`define instruction_dest(p) p["+(OFFSET_PUMP_ADDR+WIDTH_PUMP_ADDR-1)+":"+OFFSET_PUMP_ADDR+"]");
+ pw.println("`define instruction_dest(p) "+PUMP_NAME.verilogVal("p"));
pw.flush();
pw.close();
mkfunnel("funnel", prefix);
- mkhorn( "horn", prefix, WIDTH_PACKET-1, WIDTH_DEST_ADDR-1, 0, 0);
- mkhorn( "ihorn", prefix, WIDTH_PACKET-1, WIDTH_DEST_ADDR-1, 0, 0);
+ mkhorn( "horn", prefix, WIDTH_PACKET-1, WIDTH_ADDR-1, 0, 0);
+ mkhorn( "ihorn", prefix, WIDTH_PACKET-1, WIDTH_ADDR-1, 0, 0);
Module fifostage = mkfifo("fifostage", 0, null, prefix);
Module fifo4 = mkfifo("fifo4", 4, fifostage, prefix);
+ Module fifo8 = mkfifo("fifo8", 8, fifostage, prefix);
Module fifoship = mkfifo("fifo", 4, fifo4, prefix);
- mkBox("outbox", false, prefix, fifo4);
- mkBox("inbox", true, prefix, fifo4);
+ mkBox("outbox", false, prefix, fifo4, fifo8);
+ mkBox("inbox", true, prefix, fifo4, fifo8);
Module fabric = new Module("fabric");
fabric.createInputPort("horn_in", WIDTH_PACKET);
new SimpleAction("if (count_out >= 5) begin count_out <= 0; "+fabric_out.getName()+"_a <= 1; end else count_out <= count_out+1; "),
out });
PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(prefix+"/"+name+".v")));
- root.dump(pw);
+ root.dump(pw, true);
pw.flush();
return root;
}
new Action[] { in2, out,
new AssignAction(out, in2) });
PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(prefix+"/"+name+".v")));
- funnel.dump(pw);
+ funnel.dump(pw, true);
pw.flush();
return funnel;
}
driver.connect(driven);
}
PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(prefix+"/"+name+".v")));
- fifo.dump(pw);
+ fifo.dump(pw, true);
pw.flush();
return fifo;
}
horn.new Event(new Object[] { in, out0, out1, "(in["+bot_of_addr_field+"]==1)" },
new Action[] { in, out1, new AssignAction(out1, shifted_packet) });
PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(prefix+"/"+name+".v")));
- horn.dump(pw);
+ horn.dump(pw, true);
pw.flush();
}
- private static Module mkBox(String name, boolean inbox, String prefix, Module fifo) throws Exception {
+ private static Module mkBox(String name, boolean inbox, String prefix, Module fifo, Module ififo_m) throws Exception {
Module box = new Module(name);
Module.SourcePort instr = box.createInputPort("instr", WIDTH_WORD);
Module.SourcePort fabric_in = box.createInputPort("fabric_in", WIDTH_PACKET);
}
Module.Latch ondeck = box.new Latch("ondeck", WIDTH_WORD);
- Module.Latch repcount = box.new Latch("repcount", WIDTH_COUNT);
+ Module.Latch repcount = box.new Latch("repcount", WIDTH_COUNTER_LITERAL);
+ Module.Latch repcount2 = box.new Latch("repcount2", WIDTH_COUNTER_LITERAL);
+ Module.Latch killcount = box.new Latch("killcount", WIDTH_COUNTER_LITERAL);
+ Module.Latch loop_counter = box.new Latch("loop_counter", WIDTH_COUNTER_LITERAL);
+ Module.Latch repeat_counter = box.new Latch("repeat_counter", WIDTH_COUNTER_LITERAL);
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.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.InstantiatedModule ififo = box.new InstantiatedModule(ififo_m);
Module.SinkPort ififo_in = ififo.getInputPort("in");
Module.SourcePort ififo_out = ififo.getOutputPort("out");
- Value instruction_count_ondeck = ondeck .getBits(OFFSET_COUNT+WIDTH_COUNT-1, OFFSET_COUNT);
- Value instruction_count_instr = instr .getBits(OFFSET_COUNT+WIDTH_COUNT-1, OFFSET_COUNT);
- Assignable instruction_count_ififo_in = ififo_in.getAssignableBits(OFFSET_COUNT+WIDTH_COUNT-1, OFFSET_COUNT);
// Massacre (when enqueued)
box.new Event(
new Action[] { ififo_out }
);
box.new Event(
- new Object[] { ififo_out, "`instruction_is_massacre("+ififo_out.getName()+")" },
+ new Object[] { ififo_out, "`instruction_is_massacre("+ififo_out.getName()+")", isMassacreing.isFull() },
new Action[] { ififo_out, isMassacreing.doDrain(), newMayProceed.doFill() }
);
box.new Event(
- new Object[] { instr, ififo_in, "`instruction_is_massacre(instr)" },
+ new Object[] { instr, ififo_in, "`instruction_is_massacre(instr)", isMassacreing.isEmpty() },
new Action[] { instr, ififo_in, new AssignAction(ififo_in, instr), isMassacreing.doFill(), ondeckFull.doDrain(), newMayProceed.doDrain() }
);
// Clog (must be first)
box.new Event(
- new Object[] { ififo_out, newMayProceed.isFull(), "`instruction_is_clog("+ififo_out.getName()+")" },
+ new Object[] { ififo_out, newMayProceed.isFull(), "`instruction_is_clog("+ififo_out.getName()+")", isMassacreing.isEmpty() },
new Action[] { ififo_out, isClogged.doFill(), newMayProceed.doDrain() }
);
// UnClog
box.new Event(
- new Object[] { instr, isClogged.isFull(), "`instruction_is_unclog(instr)" },
+ new Object[] { instr, isClogged.isFull(), "`instruction_is_unclog(instr)", isMassacreing.isEmpty() },
new Action[] { instr, isClogged.doDrain(), newMayProceed.doFill() }
);
new Object[] { instr,
"`instruction_is_kill(instr)",
"!`instruction_is_unclog(instr)",
- ondeckFull.isFull()
+ ondeckFull.isFull(),
+ isMassacreing.isEmpty()
},
new Action[] { instr,
ondeckFull.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.doDrain()),
- new ConditionalAction("`instruction_count(instr)==0", newMayProceed.doFill())
+ new ConditionalAction("`instruction_kill_count(instr)!=0", new AssignAction(repcount, "`instruction_kill_count(instr)")),
+ new ConditionalAction("`instruction_kill_count(instr)!=0", doRepeatKill.doFill()),
+ new ConditionalAction("`instruction_kill_count(instr)!=0", newMayProceed.doDrain()),
+ new ConditionalAction("`instruction_kill_count(instr)==0", newMayProceed.doFill())
});
// Kill
box.new Event(
new Object[] { doKill.isFull() },
new Action[] { doKill.doDrain(),
- new ConditionalAction("`instruction_count(ondeck)!=0", new AssignAction(repcount, instruction_count_ondeck+"-1")),
- new ConditionalAction("`instruction_count(ondeck)!=0", doRepeatKill.doFill()),
- new ConditionalAction("`instruction_count(ondeck)==0", newMayProceed.doFill())
+ new ConditionalAction("killcount!=0", new AssignAction(repcount, "killcount-1")),
+ new ConditionalAction("killcount!=0", doRepeatKill.doFill()),
+ new ConditionalAction("killcount==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) }
+ new AssignAction(killcount, repcount) }
);
// Enqueue
box.new Event(
- new Object[] { instr, ififo_in, "!`instruction_is_kill(instr)" },
+ new Object[] { instr,
+ ififo_in,
+ "!`instruction_is_kill(instr) && !`instruction_is_unclog(instr) && !`instruction_is_massacre(instr)",
+ isMassacreing.isEmpty()
+ },
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) }
+ new Object[] { ififo_out,
+ ondeckFull.isEmpty(),
+ newMayProceed.isFull(),
+ "!`instruction_is_clog("+ififo_out.getName()+")",
+ "!`instruction_is_kill(instr)",
+ isMassacreing.isEmpty() },
+ new Action[] { ififo_out,
+ ondeckFull.doFill(),
+ newMayProceed.doDrain(),
+ new AssignAction(ondeck, ififo_out),
+ new ConditionalAction("`instruction_is_normal("+ififo_out.getName()+") && !`is_standing("+ififo_out.getName()+")",
+ new AssignAction(repcount2, "(repeat_counter==0?1:repeat_counter)")),
+ new ConditionalAction("`instruction_is_normal("+ififo_out.getName()+")",
+ new AssignAction(repeat_counter, "1")),
+ }
);
// RepeatExecute
new Object[] { doRepeat.isFull() },
new Action[] { doRepeat.doDrain(),
ondeckFull.doFill(),
- new AssignAction(instruction_count_ondeck, repcount) }
+ new AssignAction(repcount2, repcount)
+ }
);
box.addPreCrap("wire [(`DATAWIDTH-1):0] data_latch_output;");
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(),
+ isMassacreing.isEmpty(),
+ ififo_in,
+ "!`instruction_is_kill(instr)",
+ "`instruction_is_load_loop_to_data(ondeck)"
+ },
+ new Action[] { ondeckFull.doDrain(),
+ newMayProceed.doFill(),
+ new AssignAction(data_latch, loop_counter),
+ new AssignAction(ififo_in, ondeck),
+ new ConditionalAction("`should_requeue(ondeck)", ififo_in)
+ }
+ );
+ box.new Event(new Object[] { ondeckFull.isFull(),
+ isMassacreing.isEmpty(),
+ ififo_in,
+ "!`instruction_is_kill(instr)",
+ "`instruction_is_load_data_to_loop(ondeck)"
+ },
+ new Action[] { ondeckFull.doDrain(),
+ newMayProceed.doFill(),
+ new AssignAction(loop_counter, "data_latch_output"),
+ new AssignAction(ififo_in, ondeck),
+ new ConditionalAction("`should_requeue(ondeck)", ififo_in)
+ }
+ );
+ box.new Event(new Object[] { ondeckFull.isFull(),
+ isMassacreing.isEmpty(),
+ ififo_in,
+ "!`instruction_is_kill(instr)",
+ "`instruction_is_load_literal_to_loop(ondeck)"
+ },
+ new Action[] { ondeckFull.doDrain(),
+ newMayProceed.doFill(),
+ new AssignAction(loop_counter, "`instruction_loop_count_literal(ondeck)"),
+ new AssignAction(ififo_in, ondeck),
+ new ConditionalAction("`should_requeue(ondeck)", ififo_in)
+ }
+ );
+ box.new Event(new Object[] { ondeckFull.isFull(),
+ isMassacreing.isEmpty(),
+ ififo_in,
+ "!`instruction_is_kill(instr)",
+ "`instruction_is_decr_loop(ondeck)"
+ },
+ new Action[] { ondeckFull.doDrain(),
+ newMayProceed.doFill(),
+ new AssignAction(loop_counter, "loop_counter==0 ? 0 : (loop_counter-1)"),
+ new AssignAction(ififo_in, ondeck),
+ new ConditionalAction("`should_requeue(ondeck)", ififo_in)
+ }
+ );
+ box.new Event(new Object[] { ondeckFull.isFull(),
+ isMassacreing.isEmpty(),
+ ififo_in,
+ "!`instruction_is_kill(instr)",
+ "`instruction_is_load_data_to_repeat(ondeck)"
+ },
+ new Action[] { ondeckFull.doDrain(),
+ newMayProceed.doFill(),
+ new AssignAction(repeat_counter, "data_latch_output"),
+ new ConditionalAction("`should_requeue(ondeck)", new AssignAction(ififo_in, ondeck)),
+ new ConditionalAction("`should_requeue(ondeck)", ififo_in)
+ }
+ );
+ box.new Event(new Object[] { ondeckFull.isFull(),
+ isMassacreing.isEmpty(),
+ ififo_in,
+ "!`instruction_is_kill(instr)",
+ "`instruction_is_load_literal_to_repeat(ondeck)"
+ },
+ new Action[] { ondeckFull.doDrain(),
+ newMayProceed.doFill(),
+ new AssignAction(repeat_counter, "`instruction_repeat_count_literal(ondeck)"),
+ new ConditionalAction("`should_requeue(ondeck)", new AssignAction(ififo_in, ondeck)),
+ new ConditionalAction("`should_requeue(ondeck)", ififo_in)
+ }
+ );
+
+
box.new Event(
new Object[] { ondeckFull.isFull(),
isMassacreing.isEmpty(),
data_out,
token_out,
ififo_in,
- "(`instruction_is_normal(ondeck) || `instruction_is_literal(ondeck))",
+ "!`instruction_is_kill(instr)",
+ "(`instruction_is_normal(ondeck) || `instruction_is_literal_hi(ondeck) ||"+
+ " `instruction_is_literal_lo(ondeck) || `instruction_is_literal(ondeck))",
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_requeue(ondeck)", newMayProceed.doFill()),
- new ConditionalAction("`instruction_bit_requeue(ondeck) && `instruction_count(ondeck)!=1",
- new AssignAction(ififo_in, ondeck)),
- new ConditionalAction("`instruction_bit_requeue(ondeck) && `instruction_count(ondeck)!=1 && `instruction_count(ondeck)==0",
- new AssignAction(instruction_count_ififo_in, "0")),
- new ConditionalAction("`instruction_bit_requeue(ondeck) && `instruction_count(ondeck)!=1 && `instruction_count(ondeck)!=0",
- new AssignAction(instruction_count_ififo_in, instruction_count_ondeck+"-1")),
- new ConditionalAction("`instruction_bit_requeue(ondeck) && `instruction_count(ondeck)!=1", ififo_in),
- new ConditionalAction("!`instruction_bit_requeue(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 Action[] { ondeckFull.doDrain(),
+ new ConditionalAction("`done_executing(ondeck)", newMayProceed.doFill()),
+ 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("repcount2>1", doRepeat.doFill()),
+ new ConditionalAction("`is_standing(ondeck)", doRepeat.doFill()),
+ new ConditionalAction("!`is_standing(ondeck)", new AssignAction(repcount, "repcount2-1")),
new ConditionalAction("`instruction_is_literal(ondeck)",
- new AssignAction(data_latch, "`instruction_literal(ondeck,data_latch_output)")),
- 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) && (!`instruction_bit_tokenoutlast(ondeck) || `instruction_count(ondeck)==1)",
- token_out),
+ new AssignAction(data_latch, "`instruction_literal(ondeck)")),
+ new ConditionalAction("`instruction_is_literal_hi(ondeck)",
+ new AssignAction(data_latch, "`instruction_literal_hi(ondeck,data_latch_output)")),
+ new ConditionalAction("`instruction_is_literal_lo(ondeck)",
+ new AssignAction(data_latch, "`instruction_literal_lo(ondeck,data_latch_output)")),
+ 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 ConditionalAction("`instruction_path_from_data(ondeck)",
+ new AssignAction(new SimpleAssignable("`packet_dest("+token_out.getName()+")"),
+ PUMP_NAME.verilogVal(data_latch_input))),
+ new ConditionalAction("`instruction_path_from_literal(ondeck)",
new AssignAction(new SimpleAssignable("`packet_dest("+token_out.getName()+")"),
- "`instruction_bit_dest(ondeck)")),
- new ConditionalAction("`instruction_bit_dataout(ondeck) && !`instruction_bit_tokenout(ondeck)",
- inbox ? new SimpleAction("")
- : new AssignAction(new SimpleAssignable("`packet_dest("+data_out.getName()+")"),
- "`instruction_bit_dest(ondeck)")),
- new ConditionalAction("`instruction_bit_dataout(ondeck) && `instruction_bit_tokenout(ondeck) && !`instruction_bit_datain(ondeck)",
- inbox ? new SimpleAction("")
- : new AssignAction(new SimpleAssignable("`packet_dest("+data_out.getName()+")"),
- data_out.getName()+"["+(OFFSET_PUMP_ADDR+WIDTH_PUMP_ADDR-1)+":"+OFFSET_PUMP_ADDR+"]")),
- new ConditionalAction("`instruction_bit_dataout(ondeck) && `instruction_bit_tokenout(ondeck) && `instruction_bit_datain(ondeck)",
- inbox ? new SimpleAction("")
- : new AssignAction(new SimpleAssignable("`packet_dest("+data_out.getName()+")"),
- data_latch_input+"["+(OFFSET_PUMP_ADDR+WIDTH_PUMP_ADDR-1)+":"+OFFSET_PUMP_ADDR+"]"))
+ "`instruction_path_literal(ondeck)")),
}
);
PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(prefix+"/"+name+".v")));
- pw.println("`define instruction_bit_dest(instruction) instruction["+(OFFSET_DEST+WIDTH_DEST_ADDR-1)+":"+OFFSET_DEST+"]");
- pw.println("`define instruction_is_literal(i) (i["+(OFFSET_MASK_LITERAL+WIDTH_MASK_LITERAL-1)+":"+OFFSET_MASK_LITERAL+"]=="+MASK_LITERAL+")");
- pw.println("`define instruction_count(i) (`instruction_is_literal(i)?1:i["+(OFFSET_COUNT+WIDTH_COUNT-1)+":"+OFFSET_COUNT+"])");
- pw.println("`define instruction_is_kill(i) (i["+(OFFSET_MASK_KILL+WIDTH_MASK_KILL-1)+":"+OFFSET_MASK_KILL+"]=="+MASK_KILL+")");
- pw.println("`define instruction_is_unclog(i) (i["+(OFFSET_MASK_UNCLOG+WIDTH_MASK_UNCLOG-1)+":"+OFFSET_MASK_UNCLOG+"]=="+MASK_UNCLOG+")");
- pw.println("`define instruction_is_massacre(i) (i["+(OFFSET_MASK_MASSACRE+WIDTH_MASK_MASSACRE-1)+":"+OFFSET_MASK_MASSACRE+"]=="+MASK_MASSACRE+")");
- pw.println("`define instruction_is_clog(i) (i["+(OFFSET_MASK_CLOG+WIDTH_MASK_CLOG-1)+":"+OFFSET_MASK_CLOG+"]=="+MASK_CLOG+")");
- pw.println("`define instruction_is_normal(i) (i["+(OFFSET_MASK_NORMAL+WIDTH_MASK_NORMAL-1)+":"+OFFSET_MASK_NORMAL+"]=="+MASK_NORMAL+")");
- pw.println("`define instruction_bit_requeue(instruction) (instruction["+OFFSET_RQ+"] && !`instruction_is_literal(instruction))");
-
- pw.println("`define high_half(w) (w[36:19])"); // FIXME kinda ugly that we mention numbers here
- pw.println("`define low_half(w) (w[18:0])");
-
- pw.println("`define instruction_bit_tokenout(i) (!`instruction_is_literal(i) && i["+OFFSET_TO+"])");
- pw.println("`define instruction_bit_tokenoutlast(i) (!`instruction_is_literal(i) && i["+OFFSET_IG+"])");
- pw.println("`define instruction_bit_dataout(i) (!`instruction_is_literal(i) && i["+OFFSET_DO+"])");
- pw.println("`define instruction_bit_latch(i) (!`instruction_is_literal(i) && i["+OFFSET_DL+"])");
- pw.println("`define instruction_bit_datain(i) (!`instruction_is_literal(i) && i["+OFFSET_DI+"])");
- pw.println("`define instruction_bit_tokenin(i) (!`instruction_is_literal(i) && i["+OFFSET_TI+"])");
- pw.println("`define instruction_bit_literal_loadhigh(i) (i["+OFFSET_LITERAL_LOADHIGH+"])");
-
- int signextbits = WIDTH_WORD - WIDTH_LITERAL;
- /*
- pw.println("`define instruction_literal(i) {{ "+signextbits+"{i["+(OFFSET_LITERAL+WIDTH_LITERAL-1)+"]}},"+
- " i["+(OFFSET_LITERAL+WIDTH_LITERAL-1)+":"+OFFSET_LITERAL+"]}");
- */
-
- pw.println("`define instruction_literal(i,d) "+
- " (`instruction_bit_literal_loadhigh(i) "+
- " ? { (i[17:0]), (d[18:0]) } "+
- " : { (d[36:19]), (i[18:0]) }) ");
- box.dump(pw);
+ pw.println("`define instruction_is_load_loop_to_data(i) "+TAKE_LOOP.verilog("i"));
+ pw.println("`define instruction_is_load_data_to_repeat(i) "+REPEAT_FROM_DATA.verilog("i"));
+ pw.println("`define instruction_is_load_data_to_loop(i) "+LOOP_FROM_DATA.verilog("i"));
+ pw.println("`define instruction_is_load_literal_to_repeat(i) "+REPEAT_FROM_LITERAL.verilog("i"));
+ pw.println("`define instruction_is_load_literal_to_loop(i) "+LOOP_FROM_LITERAL.verilog("i"));
+ pw.println("`define instruction_repeat_count_literal(i) "+REPEAT_FROM_LITERAL.verilogVal("i"));
+ pw.println("`define instruction_loop_count_literal(i) "+LOOP_FROM_LITERAL.verilogVal("i"));
+
+ pw.println("`define instruction_path_literal(i) "+PATH_LITERAL.verilogVal("i"));
+ pw.println("`define instruction_path_from_literal(i) "+PATH_LITERAL.verilog("i"));
+ pw.println("`define instruction_path_from_data(i) "+PATH_DATA.verilog("i"));
+
+ pw.println("`define instruction_is_literal_hi(i) "+LITERAL_HI.verilog("i"));
+ pw.println("`define instruction_is_literal_lo(i) "+LITERAL_LO.verilog("i"));
+ pw.println("`define instruction_is_literal(i) "+LITERAL.verilog("i"));
+ pw.println("`define instruction_kill_count(i) "+KILL.verilogVal("i"));
+ pw.println("`define instruction_is_kill(i) "+KILL.verilog("i"));
+ pw.println("`define instruction_is_unclog(i) "+UNCLOG.verilog("i"));
+ pw.println("`define instruction_is_clog(i) "+CLOG.verilog("i"));
+ pw.println("`define instruction_is_massacre(i) "+MASSACRE.verilog("i"));
+ pw.println("`define instruction_is_normal(i) "+MOVE.verilog("i"));
+
+ pw.println("`define instruction_is_decr_loop(i) "+DL.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 is_standing(i) (`instruction_is_normal(i) && "+STAND.verilog("i")+")");
+ pw.println("`define should_requeue(i) (loop_counter > 0)");
+ pw.println("`define done_executing(i) (!`is_standing(i) && (repcount2==0 || repcount2==1))");
+
+ pw.println("`define instruction_literal_hi(i,d) { (i[17:0]), (d[18:0]) }");
+ pw.println("`define instruction_literal_lo(i,d) { (d[36:19]), (i[18:0]) }");
+
+ pw.println("`define instruction_literal_sel(i) " + LITERAL_SEL.verilogVal("i"));
+ pw.println("`define instruction_literal(i) " +
+ "("+
+ " `instruction_literal_sel(i) == 0 ? { (i[17:0]), {19{1'b0}} } "+
+ ": `instruction_literal_sel(i) == 1 ? { (i[17:0]), {19{1'b1}} } "+
+ ": `instruction_literal_sel(i) == 2 ? { {18{1'b0}}, (i[18:0]) } "+
+ ": { {18{1'b1}}, (i[18:0]) } "+
+ ")"
+ );
+
+
+ box.dump(pw, true);
pw.flush();
return box;
}
package edu.berkeley.fleet.ies44;
import edu.berkeley.fleet.api.*;
import edu.berkeley.fleet.*;
+import edu.berkeley.fleet.util.*;
import java.io.*;
import static edu.berkeley.fleet.util.BitManipulations.*;
+import static edu.berkeley.fleet.api.Instruction.*;
+import static edu.berkeley.fleet.api.Instruction.Counter.*;
public abstract class InstructionEncoder {
- public static final int WIDTH_WORD = 37; /* word width */
+ public static final int WIDTH_WORD = 37;
+ public static final int WIDTH_ADDR = 11;
public static final int WIDTH_CODEBAG_SIZE = 6;
- public static final int WIDTH_PUMP_ADDR = 11;
- public static final int WIDTH_DEST_ADDR = 11;
- public static final int WIDTH_COUNT = 7;
-
- public static final int OFFSET_MASK_LITERAL = 20;
- public static final int WIDTH_MASK_LITERAL = 6;
- public static final int MASK_LITERAL = 13; // this is an excessive approximation
-
- public static final int OFFSET_MASK_MASSACRE = 14;
- public static final int WIDTH_MASK_MASSACRE = 26-14;
- public static final int MASK_MASSACRE = 1;
-
- public static final int OFFSET_MASK_KILL = 14;
- public static final int WIDTH_MASK_KILL = 26-14;
- public static final int MASK_KILL = 0;
-
- public static final int OFFSET_MASK_UNCLOG = 14;
- public static final int WIDTH_MASK_UNCLOG = 26-14;
- public static final int MASK_UNCLOG = 3;
-
- public static final int OFFSET_MASK_CLOG = 14;
- public static final int WIDTH_MASK_CLOG = 26-14;
- public static final int MASK_CLOG = 2;
-
- public static final int OFFSET_MASK_LOAD_LOOP_TO_DATA = 14;
- public static final int WIDTH_MASK_LOAD_LOOP_TO_DATA = 12;
- public static final int MASK_LOAD_LOOP_TO_DATA = 0;
-
- public static final int OFFSET_MASK_LOAD_LITERAL_TO_LOOP = 14;
- public static final int WIDTH_MASK_LOAD_LITERAL_TO_LOOP = 12;
- public static final int MASK_LOAD_LITERAL_TO_LOOP = 1;
-
- public static final int OFFSET_MASK_LOAD_LITERAL_TO_REPEAT = 14;
- public static final int WIDTH_MASK_LOAD_LITERAL_TO_REPEAT = 12;
- public static final int MASK_LOAD_LITERAL_TO_REPEAT = 2;
-
- public static final int OFFSET_MASK_LOAD_DATA_TO_REPEAT = 14;
- public static final int WIDTH_MASK_LOAD_DATA_TO_REPEAT = 12;
- public static final int MASK_LOAD_DATA_TO_REPEAT = 3;
-
- public static final int OFFSET_MASK_LOAD_DATA_TO_LOOP = 14;
- public static final int WIDTH_MASK_LOAD_DATA_TO_LOOP = 12;
- public static final int MASK_LOAD_DATA_TO_LOOP = 4;
-
- public static final int OFFSET_MASK_DECR_LOOP = 14;
- public static final int WIDTH_MASK_DECR_LOOP = 12;
- public static final int MASK_DECR_LOOP = 5;
-
- public static final int OFFSET_MASK_NORMAL = 25;
- public static final int WIDTH_MASK_NORMAL = 1;
- public static final int MASK_NORMAL = 1;
-
- public static final int OFFSET_COUNTER_LITERAL = 0;
- public static final int WIDTH_COUNTER_LITERAL = 6;
-
- public static final int OFFSET_COUNT = 0;
- public static final int OFFSET_DEST = OFFSET_COUNT+WIDTH_COUNT;
- public static final int OFFSET_CONTROL = OFFSET_DEST+WIDTH_DEST_ADDR;
- public static final int OFFSET_RQ = OFFSET_CONTROL+0;
- public static final int OFFSET_IG = OFFSET_CONTROL+1;
- public static final int OFFSET_TO = OFFSET_CONTROL+2;
- public static final int OFFSET_DO = OFFSET_CONTROL+3;
- public static final int OFFSET_DL = OFFSET_CONTROL+4;
- public static final int OFFSET_DI = OFFSET_CONTROL+5;
- public static final int OFFSET_TI = OFFSET_CONTROL+6;
- public static final int OFFSET_LITERAL_LOADHIGH = 19;
- public static final int OFFSET_INSTRUCTIONTYPE = OFFSET_CONTROL+7;
- public static final int OFFSET_PUMP_ADDR = OFFSET_INSTRUCTIONTYPE+1;
-
- public static final int OFFSET_LITERAL = 0;
- public static final int WIDTH_LITERAL = 19;
+ public static final int WIDTH_COUNTER_LITERAL = 6;
+
+ public static final Mask REPEAT_FROM_DATA = new Mask("...............000001.........0......");
+ public static final Mask REPEAT_FROM_LITERAL = new Mask("...............000001.........1vvvvvv");
+ public static final Mask LOOP_FROM_DATA = new Mask("...............000010.........0......");
+ public static final Mask LOOP_FROM_LITERAL = new Mask("...............000010.........1vvvvvv");
+ public static final Mask TAKE_LOOP = new Mask("...............000011................");
+ public static final Mask KILL = new Mask("...............000100..........vvvvvv");
+ public static final Mask MASSACRE = new Mask("...............000101................");
+ public static final Mask CLOG = new Mask("...............000110................");
+ public static final Mask UNCLOG = new Mask("...............000111................");
+
+ public static final Mask SK = new Mask("...........1.........................");
+ public static final Mask DL = new Mask("............1........................");
+ public static final Mask P = new Mask(".............vv......................");
+ public static final Mask MOVE = new Mask("...............001...................");
+ public static final Mask STAND = new Mask("...................1.................");
+ public static final Mask TI = new Mask("....................1................");
+ public static final Mask DI = new Mask(".....................1...............");
+ public static final Mask DC = new Mask("......................1..............");
+ public static final Mask DO = new Mask(".......................1.............");
+ public static final Mask TO = new Mask("........................1............");
+ public static final Mask PATH_LITERAL = new Mask(".........................1vvvvvvvvvvv");
+ public static final Mask PATH_DATA = new Mask(".........................01..........");
+ public static final Mask PATH_NOCHANGE = new Mask(".........................00..........");
+
+ public static final Mask LITERAL_LO = new Mask("...............010vvvvvvvvvvvvvvvvvvv");
+ public static final Mask LITERAL_HI = new Mask("...............011vvvvvvvvvvvvvvvvvvv");
+ public static final Mask LITERAL = new Mask("...............1..vvvvvvvvvvvvvvvvvvv");
+ public static final Mask LITERAL_SEL = new Mask("................vv...................");
+ public static final Mask PUMP_NAME = new Mask("vvvvvvvvvvv..........................");
/** get the bits describing this box's location on the DESTINATION HORN */
}
public Instruction readInstruction(long inst) {
- Pump name = getBoxByInstAddr(getIntField(OFFSET_PUMP_ADDR+WIDTH_PUMP_ADDR-1, OFFSET_PUMP_ADDR, inst));
-
- int count_literal = getIntField(OFFSET_COUNTER_LITERAL+WIDTH_COUNTER_LITERAL-1, OFFSET_COUNTER_LITERAL, inst);
- if (getIntField(OFFSET_MASK_LOAD_LOOP_TO_DATA+WIDTH_MASK_LOAD_LOOP_TO_DATA-1, OFFSET_MASK_LOAD_LOOP_TO_DATA,inst)==MASK_LOAD_LOOP_TO_DATA)
- return new Instruction.Counter(name, Instruction.Counter.LOOP_COUNTER, Instruction.Counter.DATA_LATCH);
- else if (getIntField(OFFSET_MASK_LOAD_DATA_TO_REPEAT+WIDTH_MASK_LOAD_DATA_TO_REPEAT-1, OFFSET_MASK_LOAD_DATA_TO_REPEAT,inst)==MASK_LOAD_DATA_TO_REPEAT)
- return new Instruction.Counter(name, Instruction.Counter.DATA_LATCH, Instruction.Counter.REPEAT_COUNTER);
- else if (getIntField(OFFSET_MASK_LOAD_DATA_TO_LOOP+WIDTH_MASK_LOAD_DATA_TO_LOOP-1, OFFSET_MASK_LOAD_DATA_TO_LOOP,inst)==MASK_LOAD_DATA_TO_LOOP)
- return new Instruction.Counter(name, Instruction.Counter.DATA_LATCH, Instruction.Counter.LOOP_COUNTER);
- else if (getIntField(OFFSET_MASK_LOAD_LITERAL_TO_LOOP+WIDTH_MASK_LOAD_LITERAL_TO_LOOP-1, OFFSET_MASK_LOAD_LITERAL_TO_LOOP,inst)==MASK_LOAD_LITERAL_TO_LOOP)
- return new Instruction.Counter(name, count_literal, Instruction.Counter.LOOP_COUNTER);
- else if (getIntField(OFFSET_MASK_LOAD_LITERAL_TO_REPEAT+WIDTH_MASK_LOAD_LITERAL_TO_REPEAT-1, OFFSET_MASK_LOAD_LITERAL_TO_REPEAT,inst)==MASK_LOAD_LITERAL_TO_REPEAT)
- return new Instruction.Counter(name, count_literal, Instruction.Counter.REPEAT_COUNTER);
- else if (getIntField(OFFSET_MASK_DECR_LOOP+WIDTH_MASK_DECR_LOOP-1, OFFSET_MASK_DECR_LOOP,inst)==MASK_DECR_LOOP)
- return new Instruction.DecrLoop(name);
-
- if (getIntField(OFFSET_MASK_UNCLOG+WIDTH_MASK_UNCLOG-1, OFFSET_MASK_UNCLOG,inst)==MASK_UNCLOG)
- return new Instruction.UnClog(name);
- if (getIntField(OFFSET_MASK_CLOG+WIDTH_MASK_CLOG-1, OFFSET_MASK_CLOG,inst)==MASK_CLOG)
- return new Instruction.Clog(name);
- if (getIntField(OFFSET_MASK_MASSACRE+WIDTH_MASK_MASSACRE-1, OFFSET_MASK_MASSACRE,inst)==MASK_MASSACRE)
- return new Instruction.Massacre(name);
- int count = getIntField( OFFSET_COUNT+WIDTH_COUNT-1, OFFSET_COUNT, inst);
- if (getIntField(OFFSET_MASK_KILL+WIDTH_MASK_KILL-1, OFFSET_MASK_KILL,inst)==MASK_KILL)
- return new Instruction.Kill(name, count);
- Destination dest = getDestByAddr (getIntField(OFFSET_DEST+WIDTH_DEST_ADDR-1, OFFSET_DEST, inst));
- boolean tokenIn = getBit(OFFSET_TI, inst);
- boolean dataIn = getBit(OFFSET_DI, inst);
- boolean latch = getBit(OFFSET_DL, inst);
- boolean dataOut = getBit(OFFSET_DO, inst);
- boolean tokenOut = getBit(OFFSET_TO, inst);
- boolean requeue = getBit(OFFSET_RQ, inst);
- boolean ignoreUntilLast = getBit(OFFSET_IG, inst);
- boolean dataOutDest = name.isOutbox() && dataOut && tokenOut;
- boolean isLiteral = getIntField(OFFSET_MASK_LITERAL+WIDTH_MASK_LITERAL-1, OFFSET_MASK_LITERAL, inst)==MASK_LITERAL;
- if (isLiteral)
- return new Instruction.LocalLiteral(name, getField(OFFSET_LITERAL+WIDTH_LITERAL-1, OFFSET_LITERAL, inst), 0,
- getField(OFFSET_LITERAL_LOADHIGH, OFFSET_LITERAL_LOADHIGH, inst)!=0);
- if (dataOutDest) tokenOut = false;
+ Pump name = getBoxByInstAddr(PUMP_NAME.getval(inst));
+
+ if (LOOP_FROM_LITERAL.get(inst)) return new Counter(name, (int)LOOP_FROM_LITERAL.getval(inst), LOOP_COUNTER);
+ if (REPEAT_FROM_LITERAL.get(inst)) return new Counter(name, (int)REPEAT_FROM_LITERAL.getval(inst), REPEAT_COUNTER);
+ if (LOOP_FROM_DATA.get(inst)) return new Counter(name, DATA_LATCH, LOOP_COUNTER);
+ if (REPEAT_FROM_DATA.get(inst)) return new Counter(name, DATA_LATCH, REPEAT_COUNTER);
+ if (TAKE_LOOP.get(inst)) return new Counter(name, LOOP_COUNTER, DATA_LATCH);
+
+ if (DL.get(inst)) return new Instruction.DecrLoop(name);
+
+ if (UNCLOG.get(inst)) return new Instruction.UnClog(name);
+ if (CLOG.get(inst)) return new Instruction.Clog(name);
+ if (MASSACRE.get(inst)) return new Instruction.Massacre(name);
+ if (KILL.get(inst)) return new Instruction.Kill(name, (int)(KILL.getval(inst)+1));
+ if (LITERAL_LO.get(inst)) return new Instruction.HalfLiteral(name, LITERAL_LO.getval(inst), 0, false);
+ if (LITERAL_HI.get(inst)) return new Instruction.HalfLiteral(name, LITERAL_HI.getval(inst), 0, true);
+
+ Destination dest = getDestByAddr(PATH_LITERAL.getval(inst));
+ boolean tokenIn = TI.get(inst);
+ boolean dataIn = DI.get(inst);
+ boolean latch = DC.get(inst);
+ boolean dataOut = DO.get(inst);
+ boolean tokenOut = TO.get(inst);
+ boolean standing = STAND.get(inst);
+ boolean dataOutDest = PATH_DATA.get(inst);
return new Instruction.Move(name,
dest,
- count,
+ standing?0:1,
tokenIn,
dataIn,
latch,
dataOutDest,
dataOut,
tokenOut,
- requeue,
- ignoreUntilLast);
+ false,
+ false);
}
public long writeInstruction(Instruction d) {
long instr = 0;
if (d.pump != null)
- instr |= putField(OFFSET_PUMP_ADDR+WIDTH_PUMP_ADDR-1, OFFSET_PUMP_ADDR, getBoxInstAddr(d.pump));
+ instr = PUMP_NAME.setval(instr, getBoxInstAddr(d.pump));
if (d instanceof Instruction.CodeBagDescriptor) {
Instruction.CodeBagDescriptor lc = (Instruction.CodeBagDescriptor)d;
// MAJOR MAJOR FIXME: upper half here...
- d = new Instruction.LocalLiteral(lc.pump, ((lc.offset << WIDTH_CODEBAG_SIZE)) | lc.size, 1, false);
+ d = new Instruction.HalfLiteral(lc.pump, ((lc.offset << WIDTH_CODEBAG_SIZE)) | lc.size, 1, false);
}
if (d instanceof Instruction.UnClog) {
- instr |= putField(OFFSET_MASK_UNCLOG+WIDTH_MASK_UNCLOG-1, OFFSET_MASK_UNCLOG, MASK_UNCLOG);
+ instr = UNCLOG.set(instr);
} else if (d instanceof Instruction.Kill) {
Instruction.Kill k = (Instruction.Kill)d;
- instr |= putField(OFFSET_MASK_KILL+WIDTH_MASK_KILL-1, OFFSET_MASK_KILL, MASK_KILL);
- instr |= putField(OFFSET_COUNT+WIDTH_COUNT-1, OFFSET_COUNT, k.count-1);
+ instr = KILL.set(instr);
+ instr = KILL.setval(instr, k.count);
} else if (d instanceof Instruction.Clog) {
- instr |= putField(OFFSET_MASK_CLOG+WIDTH_MASK_CLOG-1, OFFSET_MASK_CLOG, MASK_CLOG);
+ instr = CLOG.set(instr);
} else if (d instanceof Instruction.Massacre) {
- instr |= putField(OFFSET_MASK_MASSACRE+WIDTH_MASK_MASSACRE-1, OFFSET_MASK_MASSACRE, MASK_MASSACRE);
+ instr = MASSACRE.set(instr);
- } else if (d instanceof Instruction.LocalLiteral) {
- Instruction.LocalLiteral inst = (Instruction.LocalLiteral)d;
+ } else if (d instanceof Instruction.HalfLiteral) {
+ Instruction.HalfLiteral inst = (Instruction.HalfLiteral)d;
if (inst.pump != null) {
- instr |= putField(OFFSET_MASK_LITERAL+WIDTH_MASK_LITERAL-1, OFFSET_MASK_LITERAL, MASK_LITERAL);
- instr |= putField(OFFSET_LITERAL+WIDTH_LITERAL-1, OFFSET_LITERAL, inst.literal);
- instr |= putField(OFFSET_LITERAL_LOADHIGH, OFFSET_LITERAL_LOADHIGH, (inst.high?1:0));
+ if (inst.high) {
+ instr = LITERAL_HI.set(instr);
+ instr = LITERAL_HI.setval(instr, inst.literal);
+ } else {
+ instr = LITERAL_LO.set(instr);
+ instr = LITERAL_LO.setval(instr, inst.literal);
+ }
} else {
instr = inst.literal;
}
} else if (d instanceof Instruction.DecrLoop) {
- instr |= putField(OFFSET_MASK_DECR_LOOP+WIDTH_MASK_DECR_LOOP-1, OFFSET_MASK_DECR_LOOP, MASK_DECR_LOOP);
+ instr = DL.set(instr);
} else if (d instanceof Instruction.Counter) {
Instruction.Counter ic = (Instruction.Counter)d;
- if (ic.dest == Instruction.Counter.DATA_LATCH && ic.source == Instruction.Counter.LOOP_COUNTER)
- instr |= putField(OFFSET_MASK_LOAD_LOOP_TO_DATA+WIDTH_MASK_LOAD_LOOP_TO_DATA-1,
- OFFSET_MASK_LOAD_LOOP_TO_DATA, MASK_LOAD_LOOP_TO_DATA);
- else if (ic.dest == Instruction.Counter.REPEAT_COUNTER && ic.source == Instruction.Counter.DATA_LATCH)
- instr |= putField(OFFSET_MASK_LOAD_DATA_TO_REPEAT+WIDTH_MASK_LOAD_DATA_TO_REPEAT-1,
- OFFSET_MASK_LOAD_DATA_TO_REPEAT, MASK_LOAD_DATA_TO_REPEAT);
- else if (ic.dest == Instruction.Counter.LOOP_COUNTER && ic.source == Instruction.Counter.DATA_LATCH)
- instr |= putField(OFFSET_MASK_LOAD_DATA_TO_LOOP+WIDTH_MASK_LOAD_DATA_TO_LOOP-1,
- OFFSET_MASK_LOAD_DATA_TO_LOOP, MASK_LOAD_DATA_TO_LOOP);
- else if (ic.dest == Instruction.Counter.REPEAT_COUNTER) {
- instr |= putField(OFFSET_MASK_LOAD_LITERAL_TO_REPEAT+WIDTH_MASK_LOAD_LITERAL_TO_REPEAT-1,
- OFFSET_MASK_LOAD_LITERAL_TO_REPEAT, MASK_LOAD_LITERAL_TO_REPEAT);
- instr |= putField(OFFSET_COUNTER_LITERAL+WIDTH_COUNTER_LITERAL-1,
- OFFSET_COUNTER_LITERAL, ic.source);
- } else if (ic.dest == Instruction.Counter.LOOP_COUNTER) {
- instr |= putField(OFFSET_MASK_LOAD_LITERAL_TO_LOOP+WIDTH_MASK_LOAD_LITERAL_TO_LOOP-1,
- OFFSET_MASK_LOAD_LITERAL_TO_LOOP, MASK_LOAD_LITERAL_TO_LOOP);
- instr |= putField(OFFSET_COUNTER_LITERAL+WIDTH_COUNTER_LITERAL-1,
- OFFSET_COUNTER_LITERAL, ic.source);
- } else throw new RuntimeException();
+ if (ic.dest == DATA_LATCH && ic.source == LOOP_COUNTER) instr = TAKE_LOOP.set(instr);
+ else if (ic.dest == REPEAT_COUNTER && ic.source == DATA_LATCH) instr = REPEAT_FROM_DATA.set(instr);
+ else if (ic.dest == LOOP_COUNTER && ic.source == DATA_LATCH) instr = LOOP_FROM_DATA.set(instr);
+ else if (ic.dest == REPEAT_COUNTER) instr = REPEAT_FROM_LITERAL.setval(REPEAT_FROM_LITERAL.set(instr), ic.source);
+ else if (ic.dest == LOOP_COUNTER) instr = LOOP_FROM_LITERAL.setval(LOOP_FROM_LITERAL.set(instr), ic.source);
+ else throw new RuntimeException();
} else if (d instanceof Instruction.Move) {
Instruction.Move inst = (Instruction.Move)d;
- instr |= putField(OFFSET_MASK_NORMAL+WIDTH_MASK_NORMAL-1, OFFSET_MASK_NORMAL, MASK_NORMAL);
- instr |= putField(OFFSET_DEST+WIDTH_DEST_ADDR-1, OFFSET_DEST, inst.dest==null?0:getDestAddr(inst.dest));
- instr |= putField(OFFSET_COUNT+WIDTH_COUNT-1, OFFSET_COUNT, inst.count);
- instr |= putField(OFFSET_TI, OFFSET_TI, inst.tokenIn?1:0);
- instr |= putField(OFFSET_DI, OFFSET_DI, inst.dataIn?1:0);
- instr |= putField(OFFSET_DL, OFFSET_DL, inst.latch?1:0);
- instr |= putField(OFFSET_DO, OFFSET_DO, (inst.dataOutDest||inst.dataOut)?1:0);
- instr |= putField(OFFSET_TO, OFFSET_TO, (inst.dataOutDest||inst.tokenOut)?1:0);
- instr |= putField(OFFSET_RQ, OFFSET_RQ, inst.requeue?1:0);
- instr |= putField(OFFSET_IG, OFFSET_IG, inst.ignoreUntilLast?1:0);
+ instr = MOVE.set(instr);
+ if (inst.tokenIn) instr = TI.set(instr);
+ if (inst.dataIn) instr = DI.set(instr);
+ if (inst.latch) instr = DC.set(instr);
+ if (inst.dataOut) instr = DO.set(instr);
+ if (inst.tokenOut) instr = TO.set(instr);
+ if (inst.dataOutDest) instr = PATH_DATA.set(instr);
+ else {
+ instr = PATH_LITERAL.set(instr);
+ instr = PATH_LITERAL.setval(instr, inst.dest==null?0:getDestAddr(inst.dest));
+ }
+ if (inst.standing) instr = STAND.set(instr);
}
return instr;
protected long peekDataLatch() { return register.value; }
/** invoked by superclass */
- protected final boolean service(Instruction.Executable instruction_) {
+ protected final boolean service(Instruction instruction_) {
// if data is stuck on itemPresentedToShip, wait for it to go somewhere before
// considering additional instructions
// if no instruction waiting, do nothing
if (instruction_ == null) return false;
- if (clogged>0) return false;
- if (instruction_ instanceof Instruction.Clog) { clogged++; return true; }
- if (instruction_ instanceof Instruction.LocalLiteral) {
- Instruction.LocalLiteral ll = (Instruction.LocalLiteral)instruction_;
+ if (instruction_ instanceof Instruction.HalfLiteral) {
+ Instruction.HalfLiteral ll = (Instruction.HalfLiteral)instruction_;
long val = (register==null) ? 0 : register.value;
val =
ll.high
public int clogged = 0;
/** the currently executing instruction */
- private Instruction.Executable executing = null;
+ private Instruction executing = null;
/** all instructions waiting to be executed (excludes executing) */
- private Queue<Instruction.Executable> instructions = new LinkedList<Instruction.Executable>();
+ private Queue<Instruction> instructions = new LinkedList<Instruction>();
/** count of how many "standing instruction only" kills remain to be executed */
private int killNextStandingInstruction = 0;
public int loopCounter = 0;
+ public int repeatCounter = 1;
InstructionPump(InterpreterShip ship, String name, String[] ports) {
super(ship, name, ports);
}
/** an instruction arrives from the instruction horn */
- void addInstruction(Instruction.Executable instr) {
+ void addInstruction(Instruction instr) {
if (killNextStandingInstruction > 0) { /* FIXME technically we should refuse to take the next instruction here */ }
instructions.add(instr);
}
this + "; they are:"));
if (executing != null)
Log.println(" " + executing);
- for(Instruction.Executable i : instructions)
+ for(Instruction i : instructions)
Log.println(" " + i);
}
// interface to subclass ///////////////////////////////////////////////////////////////////////
/** this will be invoked periodically; should return true to "consume" an instruction, false to leave it executing */
- protected abstract boolean service(Instruction.Executable instr);
+ protected abstract boolean service(Instruction instr);
protected abstract void setDataLatch(long value);
protected abstract long peekDataLatch();
- public boolean _service(Instruction.Executable instr) {
- if (instr instanceof Instruction.DecrLoop) {
- if (loopCounter >= 0) loopCounter--;
- return true;
- }
- if (instr instanceof Instruction.Counter) {
- Instruction.Counter ic = (Instruction.Counter)instr;
+
+ protected final void service() {
+ if (clogged > 0) return;
+ if (executing==null && instructions.size() > 0) executing = instructions.remove();
+ if (executing==null) return;
+
+ int oldLoopCounter = loopCounter;
+ if (executing.isDL()) loopCounter = Math.max(0, loopCounter-1);
+
+ if (executing instanceof Instruction.Counter) {
+ Instruction.Counter ic = (Instruction.Counter)executing;
if (ic.source == Instruction.Counter.LOOP_COUNTER && ic.dest == Instruction.Counter.DATA_LATCH) {
setDataLatch(loopCounter);
} else if (ic.dest == Instruction.Counter.LOOP_COUNTER && ic.source == Instruction.Counter.DATA_LATCH) {
loopCounter = (int)peekDataLatch();
- executing = null;
+ } else if (ic.dest == Instruction.Counter.REPEAT_COUNTER && ic.source == Instruction.Counter.DATA_LATCH) {
+ repeatCounter = (int)peekDataLatch();
} else if (ic.dest == Instruction.Counter.LOOP_COUNTER) {
loopCounter = ic.source;
- executing = null;
+ } else if (ic.dest == Instruction.Counter.REPEAT_COUNTER) {
+ repeatCounter = ic.source;
}
- return true;
- }
- return service(instr);
- }
-
- protected final void service() {
- if (executing == null)
- if (instructions.size() > 0)
- executing = instructions.remove();
- else
- return;
-
- if (executing != null && killNextStandingInstruction>0 && executing.isStanding()) {
+ } else if (executing instanceof Instruction.DecrLoop) {
+ executing = null;
+ return;
+ } else if (executing instanceof Instruction.Clog) {
+ clogged++;
executing = null;
- killNextStandingInstruction--;
return;
+ } else {
+ if (!service(executing)) return;
}
- boolean ret = _service(executing);
- if (!ret) return;
- if (executing == null) return;
- if (executing.isRequeueing() || (loopCounter > 0)) {
- if (loopCounter == 0) executing = executing.decrementCount();
- if (executing != null)
- addInstruction(executing);
+ if (executing==null) return;
+ if (executing.isRepeating() && repeatCounter > 1) {
+ repeatCounter--;
+ } else if (executing.isLooping() && oldLoopCounter > 0) {
+ addInstruction(executing);
executing = null;
-
+ } else if (executing.isStanding()) {
} else {
- if (executing != null && !executing.isStanding())
- executing = executing.decrementCount();
+ executing = null;
}
}
public void dispatch(Instruction i, long address) {
Log.dispatch(i);
- if (i instanceof Instruction.Executable) {
- InterpreterPump sourcePump = (InterpreterPump)(((Instruction.Executable)i).pump);
- ((InstructionPump)sourcePump).addInstruction(((Instruction.Executable)i));
-
- } else if (i instanceof Instruction.CodeBagDescriptor) {
+ if (i instanceof Instruction.CodeBagDescriptor) {
Instruction.CodeBagDescriptor cbd = (Instruction.CodeBagDescriptor)i;
long absolute_cbd = ((cbd.offset+address) << 6) | cbd.size;
throw new RuntimeException();
((InstructionPump)pump).massacre();
} else {
- throw new Error("unsupported: " + i.getClass().getName());
+ InterpreterPump sourcePump = (InterpreterPump)(((Instruction)i).pump);
+ ((InstructionPump)sourcePump).addInstruction(((Instruction)i));
}
}
protected void setDataLatch(long value) { register = value; }
protected long peekDataLatch() { return register; }
- protected final boolean service(Instruction.Executable instruction_) {
- if (clogged>0) return false;
- if (instruction_ instanceof Instruction.Clog) { clogged++; return true; }
- if (instruction_ instanceof Instruction.LocalLiteral) {
- Instruction.LocalLiteral ll = (Instruction.LocalLiteral)instruction_;
+ protected final boolean service(Instruction instruction_) {
+ if (instruction_ instanceof Instruction.HalfLiteral) {
+ Instruction.HalfLiteral ll = (Instruction.HalfLiteral)instruction_;
register =
ll.high
? setField(36, 19, ll.literal, register)
InterpreterDestination dest = (InterpreterDestination)instruction.dest;
if (instruction.dataOutDest) {
// FIXME: still not supported
- long bits = BitManipulations.getField(InstructionEncoder.OFFSET_PUMP_ADDR+InstructionEncoder.WIDTH_PUMP_ADDR-1,
- InstructionEncoder.OFFSET_PUMP_ADDR,
- register);
+ long bits = InstructionEncoder.PUMP_NAME.getval(register);
getInterpreter().dispatch(((Interpreter)getInterpreter()).iie.readInstruction(register), bits);
/*
dest = (InterpreterDestination)(((Interpreter)getInterpreter()).iie.getDestByAddr(bits));
--- /dev/null
+package edu.berkeley.fleet.util;
+import edu.berkeley.fleet.api.*;
+import edu.berkeley.fleet.*;
+import java.io.*;
+
+public class Mask {
+
+ public final long mask;
+ public final long val;
+ public final long valmask;
+ public final int valmaskmin;
+
+
+ public String verilog(String var) {
+ return "(("+var+" & "+mask+")=="+val+")";
+ }
+ public String verilogVal(String var) {
+ return "(("+var+" & "+valmask+") >> "+valmaskmin+")";
+ }
+
+ public long getval(long in) {
+ return (in & valmask) >>> valmaskmin;
+ }
+ public long setval(long in, long targ) {
+ if (((targ << valmaskmin) & ~valmask) != 0) throw new RuntimeException("setval() with argument bigger than mask field");
+ return (in & ~valmask) | ((targ << valmaskmin) & valmask);
+ }
+ public long set(long in) {
+ return (in & ~mask) | val;
+ }
+ public boolean get(long in) {
+ return (in & mask) == val;
+ }
+
+ public Mask(String s) {
+ long mask = 0;
+ long valmask = 0;
+ long val = 0;
+ int valmaskmin = Integer.MAX_VALUE;
+ for(int i=0; i<s.length(); i++) {
+ char c = s.charAt(s.length()-1-i);
+ switch(c) {
+ case '.': break;
+ case '0': mask |= (1<<i); val |= (0<<i); break;
+ case '1': mask |= (1<<i); val |= (1<<i); break;
+ case 'v': valmask |= (1<<i); valmaskmin = Math.min(valmaskmin,i); break;
+ default: throw new Error(""+c);
+ }
+ }
+ this.mask = mask;
+ this.val = val;
+ this.valmask = valmask;
+ this.valmaskmin = valmaskmin;
+ }
+
+}
\ No newline at end of file