From bc8c0436bf0c09f63df883dcdf6583da0f7ec705 Mon Sep 17 00:00:00 2001 From: adam Date: Tue, 12 Feb 2008 07:58:54 +0100 Subject: [PATCH] add support for a "standing" count value --- src/edu/berkeley/fleet/api/Instruction.java | 5 ++- src/edu/berkeley/fleet/assembler/Parser.java | 3 ++ src/edu/berkeley/fleet/assembler/fleet.g | 1 + src/edu/berkeley/fleet/fpga/Generator.java | 43 ++++++++++++++------ .../berkeley/fleet/ies44/InstructionEncoder.java | 39 ++++++++++-------- .../fleet/interpreter/InstructionPump.java | 7 +++- 6 files changed, 66 insertions(+), 32 deletions(-) diff --git a/src/edu/berkeley/fleet/api/Instruction.java b/src/edu/berkeley/fleet/api/Instruction.java index 321795a..3521374 100644 --- a/src/edu/berkeley/fleet/api/Instruction.java +++ b/src/edu/berkeley/fleet/api/Instruction.java @@ -105,6 +105,7 @@ public abstract class Instruction { 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); } @@ -123,7 +124,9 @@ public abstract class Instruction { 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"); diff --git a/src/edu/berkeley/fleet/assembler/Parser.java b/src/edu/berkeley/fleet/assembler/Parser.java index ec0b4c6..574633e 100644 --- a/src/edu/berkeley/fleet/assembler/Parser.java +++ b/src/edu/berkeley/fleet/assembler/Parser.java @@ -302,6 +302,9 @@ public class Parser { } 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; diff --git a/src/edu/berkeley/fleet/assembler/fleet.g b/src/edu/berkeley/fleet/assembler/fleet.g index b674b3a..de5e101 100644 --- a/src/edu/berkeley/fleet/assembler/fleet.g +++ b/src/edu/berkeley/fleet/assembler/fleet.g @@ -22,6 +22,7 @@ InstructionX = ^"unclog" ";" /ws | "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 diff --git a/src/edu/berkeley/fleet/fpga/Generator.java b/src/edu/berkeley/fleet/fpga/Generator.java index 461ddaf..3132491 100644 --- a/src/edu/berkeley/fleet/fpga/Generator.java +++ b/src/edu/berkeley/fleet/fpga/Generator.java @@ -579,11 +579,11 @@ public class Generator { } 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); @@ -782,6 +782,19 @@ public class Generator { 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( @@ -800,9 +813,12 @@ public class Generator { 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)", @@ -825,13 +841,14 @@ public class Generator { 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")); @@ -858,6 +875,8 @@ public class Generator { 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]) }"); diff --git a/src/edu/berkeley/fleet/ies44/InstructionEncoder.java b/src/edu/berkeley/fleet/ies44/InstructionEncoder.java index 8dc44b7..2efe2a6 100644 --- a/src/edu/berkeley/fleet/ies44/InstructionEncoder.java +++ b/src/edu/berkeley/fleet/ies44/InstructionEncoder.java @@ -14,18 +14,19 @@ public abstract class InstructionEncoder { 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........................"); @@ -94,11 +95,12 @@ public abstract class InstructionEncoder { 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); @@ -193,8 +195,9 @@ public abstract class InstructionEncoder { } 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(); diff --git a/src/edu/berkeley/fleet/interpreter/InstructionPump.java b/src/edu/berkeley/fleet/interpreter/InstructionPump.java index 8e7fd82..3c06ccf 100644 --- a/src/edu/berkeley/fleet/interpreter/InstructionPump.java +++ b/src/edu/berkeley/fleet/interpreter/InstructionPump.java @@ -24,7 +24,7 @@ abstract class InstructionPump extends InterpreterPump { 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); @@ -108,9 +108,12 @@ abstract class InstructionPump extends InterpreterPump { } 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; } @@ -148,6 +151,8 @@ abstract class InstructionPump extends InterpreterPump { 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; -- 1.7.10.4