public static final int DATA_LATCH = -1;
public static final int REPEAT_COUNTER = -2;
public static final int LOOP_COUNTER = -3;
+ public static final int STANDING = -3;
public final int source;
public final int dest;
public Counter(Pump pump, int source, int dest) { this(pump, P_ALWAYS, source, dest); }
default: throw new RuntimeException("invalid");
}
ret.append(" counter");
- if (source >= 0) {
+ if (source == STANDING)
+ ret.append(" with *");
+ else if (source >= 0) {
ret.append(" with " + source);
} else if (source!=DATA_LATCH) {
throw new RuntimeException("invalid");
} else if ("load".equals(tt.head()) && "repeat".equals(tt.child(0).head())) {
cb.add(new Instruction.Counter(pump, predicate, Instruction.Counter.DATA_LATCH, Instruction.Counter.REPEAT_COUNTER));
continue;
+ } else if ("*".equals(tt.head())) {
+ cb.add(new Instruction.Counter(pump, predicate, Instruction.Counter.STANDING, Instruction.Counter.REPEAT_COUNTER));
+ continue;
} else if ("with".equals(tt.head()) && "loop".equals(tt.child(0).head())) {
cb.add(new Instruction.Counter(pump, predicate, (int)number(tt.child(1)), Instruction.Counter.LOOP_COUNTER));
continue;
| "take" ^"loop" "counter" ";" /ws
| ^"load" (^"loop"|^"repeat") ws "counter" ";" /ws
| "load" (^"loop"|^"repeat") ws "counter" ^"with" int ";" /ws
+ | "load" (^"loop"|^"repeat") ws "counter" "with" ^"*" ";" /ws
| ^"decrement" "loop" "counter" ";" /ws
| ^"setflags" "a" "=" Flags "," "b" "=" Flags ";" /ws
| ^"kill" int ";" /ws
}
Module.Latch ondeck = box.new Latch("ondeck", WIDTH_WORD);
- Module.Latch repcount = box.new Latch("repcount", WIDTH_COUNTER_LITERAL);
- Module.Latch repcount2 = box.new Latch("repcount2", WIDTH_COUNTER_LITERAL);
+ Module.Latch repcount = box.new Latch("repcount", WIDTH_COUNTER_LITERAL+1);
+ Module.Latch repcount2 = box.new Latch("repcount2", WIDTH_COUNTER_LITERAL+1);
+ Module.Latch repeat_counter = box.new Latch("repeat_counter", WIDTH_COUNTER_LITERAL+1);
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);
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_standing_to_repeat(ondeck)"
+ },
+ new Action[] { ondeckFull.doDrain(),
+ newMayProceed.doFill(),
+ new AssignAction(repeat_counter, "`magic_standing_value"),
+ new ConditionalAction("`should_requeue(ondeck)", new AssignAction(ififo_in, ondeck)),
+ new ConditionalAction("`should_requeue(ondeck)", ififo_in)
+ }
+ );
box.new Event(
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("repcount2>1 || repcount2==`magic_standing_value", doRepeat.doFill()),
new ConditionalAction("`is_standing(ondeck)", doRepeat.doFill()),
- new ConditionalAction("!`is_standing(ondeck)", new AssignAction(repcount, "repcount2-1")),
+ new ConditionalAction("!`is_standing(ondeck) && repcount2!=`magic_standing_value",
+ new AssignAction(repcount, "repcount2-1")),
+ new ConditionalAction("!`is_standing(ondeck) && repcount2==`magic_standing_value",
+ new AssignAction(repcount, "`magic_standing_value")),
new ConditionalAction("`instruction_is_literal(ondeck)",
new AssignAction(data_latch, "`instruction_literal(ondeck)")),
new ConditionalAction("`instruction_is_literal_hi(ondeck)",
PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(prefix+"/"+name+".v")));
- 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_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_is_load_standing_to_repeat(i) "+REPEAT_FROM_STANDING.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 should_requeue(i) (loop_counter > 0)");
pw.println("`define done_executing(i) (!`is_standing(i) && (repcount2==0 || repcount2==1))");
+ pw.println("`define magic_standing_value (1<<"+WIDTH_COUNTER_LITERAL+")");
+
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]) }");
public static final int WIDTH_CODEBAG_SIZE = 6;
public static final int WIDTH_COUNTER_LITERAL = 6;
- public static final Mask FLAGS = new Mask("...............000000................");
- public static final Mask FLAGS_A = new Mask("...............000000vvvvvvvv........");
- public static final Mask FLAGS_B = new Mask("...............000000........vvvvvvvv");
- 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 FLAGS = new Mask("...............000000................");
+ public static final Mask FLAGS_A = new Mask("...............000000vvvvvvvv........");
+ public static final Mask FLAGS_B = new Mask("...............000000........vvvvvvvv");
+ public static final Mask REPEAT_FROM_DATA = new Mask("...............000001........00......");
+ public static final Mask REPEAT_FROM_LITERAL = new Mask("...............000001........10vvvvvv");
+ public static final Mask REPEAT_FROM_STANDING = new Mask("...............000001........11......");
+ 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........................");
if (P_B.get(inst)) predicate = Instruction.PredicatedInstruction.P_IF_B;
if (P_Z.get(inst)) predicate = Instruction.PredicatedInstruction.P_IF_Z;
- if (LOOP_FROM_LITERAL.get(inst)) return new Counter(name, predicate, (int)LOOP_FROM_LITERAL.getval(inst), LOOP_COUNTER);
- if (REPEAT_FROM_LITERAL.get(inst)) return new Counter(name, predicate, (int)REPEAT_FROM_LITERAL.getval(inst), REPEAT_COUNTER);
- if (LOOP_FROM_DATA.get(inst)) return new Counter(name, predicate, DATA_LATCH, LOOP_COUNTER);
- if (REPEAT_FROM_DATA.get(inst)) return new Counter(name, predicate, DATA_LATCH, REPEAT_COUNTER);
- if (TAKE_LOOP.get(inst)) return new Counter(name, predicate, LOOP_COUNTER, DATA_LATCH);
+ if (LOOP_FROM_LITERAL.get(inst)) return new Counter(name, predicate, (int)LOOP_FROM_LITERAL.getval(inst), LOOP_COUNTER);
+ if (REPEAT_FROM_LITERAL.get(inst)) return new Counter(name, predicate, (int)REPEAT_FROM_LITERAL.getval(inst), REPEAT_COUNTER);
+ if (LOOP_FROM_DATA.get(inst)) return new Counter(name, predicate, DATA_LATCH, LOOP_COUNTER);
+ if (REPEAT_FROM_DATA.get(inst)) return new Counter(name, predicate, DATA_LATCH, REPEAT_COUNTER);
+ if (REPEAT_FROM_STANDING.get(inst)) return new Counter(name, predicate, STANDING, REPEAT_COUNTER);
+ if (TAKE_LOOP.get(inst)) return new Counter(name, predicate, LOOP_COUNTER, DATA_LATCH);
if (DL.get(inst)) return new Instruction.DecrLoop(name, predicate);
} else if (d instanceof Instruction.Counter) {
Instruction.Counter ic = (Instruction.Counter)d;
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 && ic.source == DATA_LATCH) instr = REPEAT_FROM_DATA.set(instr);
+ else if (ic.dest == REPEAT_COUNTER && ic.source == STANDING) instr = REPEAT_FROM_STANDING.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();
private int killNextStandingInstruction = 0;
public int loopCounter = 0;
- public int repeatCounter = 1;
+ private int repeatCounter = 1;
InstructionPump(InterpreterShip ship, String name, String[] ports) {
super(ship, name, ports);
} else if (ic.dest == Instruction.Counter.LOOP_COUNTER && ic.source == Instruction.Counter.DATA_LATCH) {
loopCounter = (int)peekDataLatch();
} else if (ic.dest == Instruction.Counter.REPEAT_COUNTER && ic.source == Instruction.Counter.DATA_LATCH) {
+ // FIXME: is there any way to load the "standing" value?
repeatCounter = (int)peekDataLatch();
} else if (ic.dest == Instruction.Counter.LOOP_COUNTER) {
loopCounter = ic.source;
+ } else if (ic.dest == Instruction.Counter.REPEAT_COUNTER && ic.source==Instruction.Counter.STANDING) {
+ repeatCounter = -1;
} else if (ic.dest == Instruction.Counter.REPEAT_COUNTER) {
repeatCounter = ic.source;
}
if (executing==null) return;
if (executing.isRepeating() && repeatCounter > 1) {
repeatCounter--;
+ } else if (executing.isRepeating() && repeatCounter == -1) {
+ // repeat
} else if (executing.isLooping() && oldLoopCounter > 0) {
addInstruction(executing);
executing = null;