From 36a3b192a635ad13c0f102c5f2439016f1b608f8 Mon Sep 17 00:00:00 2001 From: adam Date: Fri, 25 Jan 2008 03:57:55 +0100 Subject: [PATCH] major overhaul: update dock to am33 --- src/edu/berkeley/fleet/api/Instruction.java | 95 +++--- src/edu/berkeley/fleet/assembler/Parser.java | 6 +- src/edu/berkeley/fleet/fpga/Fpga.java | 11 +- src/edu/berkeley/fleet/fpga/Generator.java | 322 +++++++++++++------- .../berkeley/fleet/ies44/InstructionEncoder.java | 256 ++++++---------- src/edu/berkeley/fleet/interpreter/Inbox.java | 8 +- .../fleet/interpreter/InstructionPump.java | 73 +++-- .../berkeley/fleet/interpreter/Interpreter.java | 9 +- src/edu/berkeley/fleet/interpreter/Outbox.java | 12 +- src/edu/berkeley/fleet/util/Mask.java | 56 ++++ 10 files changed, 470 insertions(+), 378 deletions(-) create mode 100644 src/edu/berkeley/fleet/util/Mask.java diff --git a/src/edu/berkeley/fleet/api/Instruction.java b/src/edu/berkeley/fleet/api/Instruction.java index 851718d..4cfe0b2 100644 --- a/src/edu/berkeley/fleet/api/Instruction.java +++ b/src/edu/berkeley/fleet/api/Instruction.java @@ -6,15 +6,15 @@ public abstract class Instruction { 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 { @@ -26,40 +26,25 @@ public abstract class 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; } @@ -81,9 +66,10 @@ public abstract class Instruction { 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; @@ -94,8 +80,7 @@ public abstract class Instruction { 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, @@ -109,7 +94,7 @@ public abstract class Instruction { boolean tokenOut, boolean requeue, boolean ignoreUntilLast) { - super(pump, count); + super(pump); this.dest = dest; this.tokenIn = tokenIn; this.dataIn = dataIn; @@ -119,8 +104,7 @@ public abstract class Instruction { 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) @@ -129,12 +113,6 @@ public abstract class Instruction { 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(); @@ -159,21 +137,36 @@ public abstract class Instruction { 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 { diff --git a/src/edu/berkeley/fleet/assembler/Parser.java b/src/edu/berkeley/fleet/assembler/Parser.java index 0e58b3f..dcd5289 100644 --- a/src/edu/berkeley/fleet/assembler/Parser.java +++ b/src/edu/berkeley/fleet/assembler/Parser.java @@ -312,8 +312,8 @@ public class Parser { } 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; @@ -355,7 +355,7 @@ public class Parser { 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)); } diff --git a/src/edu/berkeley/fleet/fpga/Fpga.java b/src/edu/berkeley/fleet/fpga/Fpga.java index 72a7597..f5815a8 100644 --- a/src/edu/berkeley/fleet/fpga/Fpga.java +++ b/src/edu/berkeley/fleet/fpga/Fpga.java @@ -32,17 +32,20 @@ public class Fpga extends Fleet { 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"); diff --git a/src/edu/berkeley/fleet/fpga/Generator.java b/src/edu/berkeley/fleet/fpga/Generator.java index 13d8a4c..e0882f7 100644 --- a/src/edu/berkeley/fleet/fpga/Generator.java +++ b/src/edu/berkeley/fleet/fpga/Generator.java @@ -15,7 +15,7 @@ import static edu.berkeley.fleet.ies44.InstructionEncoder.*; 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; @@ -175,7 +175,7 @@ public class Generator { 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;"); } } @@ -325,7 +325,7 @@ public class Generator { } } - 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) { @@ -366,7 +366,7 @@ public class Generator { } } - for(Event a : events) a.dump(pw); + for(Event a : events) a.dump(pw, fix); pw.println(" begin end"); pw.println("end"); @@ -386,7 +386,7 @@ public class Generator { 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()); @@ -394,7 +394,8 @@ public class Generator { } 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 "); } } } @@ -406,28 +407,31 @@ public class Generator { 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); @@ -456,7 +460,7 @@ public class Generator { 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; } @@ -473,7 +477,7 @@ public class Generator { 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; } @@ -493,7 +497,7 @@ public class Generator { 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; } @@ -519,11 +523,11 @@ public class Generator { 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); @@ -545,7 +549,11 @@ public class Generator { } 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); @@ -559,13 +567,10 @@ public class Generator { 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( @@ -573,23 +578,23 @@ public class Generator { 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() } ); @@ -598,43 +603,60 @@ public class Generator { 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 @@ -642,7 +664,8 @@ public class Generator { 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;"); @@ -651,88 +674,175 @@ public class Generator { 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; } diff --git a/src/edu/berkeley/fleet/ies44/InstructionEncoder.java b/src/edu/berkeley/fleet/ies44/InstructionEncoder.java index 5e4571f..cabdca4 100644 --- a/src/edu/berkeley/fleet/ies44/InstructionEncoder.java +++ b/src/edu/berkeley/fleet/ies44/InstructionEncoder.java @@ -1,84 +1,48 @@ 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 */ @@ -110,132 +74,110 @@ public abstract class InstructionEncoder { } 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; diff --git a/src/edu/berkeley/fleet/interpreter/Inbox.java b/src/edu/berkeley/fleet/interpreter/Inbox.java index a00be0f..c4ec8cf 100644 --- a/src/edu/berkeley/fleet/interpreter/Inbox.java +++ b/src/edu/berkeley/fleet/interpreter/Inbox.java @@ -45,7 +45,7 @@ public class Inbox extends InstructionPump { 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 @@ -54,10 +54,8 @@ public class Inbox extends InstructionPump { // 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 diff --git a/src/edu/berkeley/fleet/interpreter/InstructionPump.java b/src/edu/berkeley/fleet/interpreter/InstructionPump.java index 945e863..b600615 100644 --- a/src/edu/berkeley/fleet/interpreter/InstructionPump.java +++ b/src/edu/berkeley/fleet/interpreter/InstructionPump.java @@ -12,15 +12,16 @@ abstract class InstructionPump extends InterpreterPump { 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 instructions = new LinkedList(); + private Queue instructions = new LinkedList(); /** 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); @@ -48,7 +49,7 @@ abstract class InstructionPump extends InterpreterPump { } /** 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); } @@ -59,63 +60,59 @@ abstract class InstructionPump extends InterpreterPump { 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; } } diff --git a/src/edu/berkeley/fleet/interpreter/Interpreter.java b/src/edu/berkeley/fleet/interpreter/Interpreter.java index 507090d..3a25f4a 100644 --- a/src/edu/berkeley/fleet/interpreter/Interpreter.java +++ b/src/edu/berkeley/fleet/interpreter/Interpreter.java @@ -81,11 +81,7 @@ public class Interpreter extends Fleet implements Fleet.WithDynamicShips { 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(); @@ -104,7 +100,8 @@ public class Interpreter extends Fleet implements Fleet.WithDynamicShips { ((InstructionPump)pump).massacre(); } else { - throw new Error("unsupported: " + i.getClass().getName()); + InterpreterPump sourcePump = (InterpreterPump)(((Instruction)i).pump); + ((InstructionPump)sourcePump).addInstruction(((Instruction)i)); } } diff --git a/src/edu/berkeley/fleet/interpreter/Outbox.java b/src/edu/berkeley/fleet/interpreter/Outbox.java index 85b3926..ff7e8e2 100644 --- a/src/edu/berkeley/fleet/interpreter/Outbox.java +++ b/src/edu/berkeley/fleet/interpreter/Outbox.java @@ -30,11 +30,9 @@ public class Outbox extends InstructionPump { 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) @@ -68,9 +66,7 @@ public class Outbox extends InstructionPump { 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)); diff --git a/src/edu/berkeley/fleet/util/Mask.java b/src/edu/berkeley/fleet/util/Mask.java new file mode 100644 index 0000000..f75c4be --- /dev/null +++ b/src/edu/berkeley/fleet/util/Mask.java @@ -0,0 +1,56 @@ +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