import edu.berkeley.sbp.util.ANSI;
import edu.berkeley.fleet.api.*;
import edu.berkeley.fleet.fpga.*;
-import edu.berkeley.fleet.doc.*;
import edu.berkeley.fleet.interpreter.*;
+import edu.berkeley.fleet.two.*;
+import edu.berkeley.fleet.util.*;
import java.io.*;
import java.util.*;
Fleet fleet;
if ("fpga".equals(target)) {
String bitfile = options.get("bitfile");
- fleet = bitfile == null ? new Fpga() : new Fpga(bitfile);
+ fleet = new Fpga();
} else if ("sim".equals(target) || "fleetsim".equals(target)) {
fleet = (Fleet)Class.forName("com.sunlabs.fleetsim.fleet.FleetDescription").newInstance();
} else {
if (command.equals("run")) {
InputStream is;
- if (args.size()==0) {
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- Reader r = new InputStreamReader(System.in);
- edu.berkeley.fleet.assembler.Main.assemble(fleet, r, baos);
- is = new ByteArrayInputStream(baos.toByteArray());
- } else {
- String filename = args.get(0);
- if (filename.endsWith(".fa") || filename.endsWith(".fleet")) {
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- Reader r = new InputStreamReader(new FileInputStream(args.get(0)));
- edu.berkeley.fleet.assembler.Main.assemble(fleet, r, baos);
- is = new ByteArrayInputStream(baos.toByteArray());
- } else {
- is = new FileInputStream(args.get(0));
- }
- }
- run(fleet, is);
+ String filename = args.get(0);
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ Reader r = new InputStreamReader(new FileInputStream(args.get(0)));
+ run(fleet, edu.berkeley.fleet.assembler.Main.assemble(fleet, r));
} else if (command.equals("expand")) {
- fleet.expand(new ShipDescription(args.get(0), new BufferedReader(new InputStreamReader(new FileInputStream(args.get(0))))));
+ String name = new File(args.get(0)).getName();
+ if (name.endsWith(".ship"))
+ name = name.substring(0, name.length() - ".ship".length());
+ if (fleet instanceof edu.berkeley.fleet.fpga.Fpga) {
+ ((edu.berkeley.fleet.fpga.Fpga)fleet).expand(new ShipDescription(name, new BufferedReader(new InputStreamReader(new FileInputStream(args.get(0))))));
+ } else {
+ ((Interpreter)fleet).expand(new ShipDescription(name, new BufferedReader(new InputStreamReader(new FileInputStream(args.get(0))))));
+ }
} else if (command.equals("doc")) {
- Doc.print();
+ if (!new File(".tmp").exists())
+ new File(".tmp").mkdirs();
+ PrintWriter pw = new PrintWriter(new FileOutputStream(".tmp/FleetTwo.Manual.tex"));
+ BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("doc/archman.tex")));
+ for(String ss = br.readLine(); ss!=null; ss = br.readLine())
+ pw.println(ss);
+ for(String f : new File("ships").list()) {
+ new ShipDescription(f, new BufferedReader(new InputStreamReader(new FileInputStream(new File("ships/"+f))))).printTeX(pw);
+ }
+ pw.println("\\end{document}");
+ pw.close();
} else if (command.equals("test")) {
for(int i=0; i<args.size(); i++)
test(fleet, new File(args.get(i)));
- } else if (command.equals("asm")) {
- String filename = args.get(0);
- FileOutputStream out = new FileOutputStream("fleet.fo");
- Reader r = new InputStreamReader(new FileInputStream(args.get(0)));
- edu.berkeley.fleet.assembler.Main.assemble(fleet, r, out);
- out.flush();
-
} else {
usage();
System.exit(-1);
}
static void runTest(Fleet fleet, Reader reader, String title) throws Exception {
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- edu.berkeley.fleet.assembler.Main.assemble(fleet, reader, baos);
+ Instruction[] instructions = edu.berkeley.fleet.assembler.Main.assemble(fleet, reader);
if (edu.berkeley.fleet.assembler.Parser.skip) {
System.out.println("\r[" + ANSI.yellow("SKIP") +
"] " + ANSI.yellow(title));
edu.berkeley.fleet.assembler.Parser.skip = false;
return;
}
- FleetProcess fp = fleet.run(baos.toByteArray());
+ FleetProcess fp = fleet.run(instructions);
+ //long now = System.currentTimeMillis();
try {
ArrayList<Long> expect = edu.berkeley.fleet.assembler.Parser.expect;
String output = "";
System.out.print("\r" + verdict + " " + ANSI.yellow(title) + ": " + output);
if (failed) break;
if (expect.size() == 0) break;
- long l = fp.readWord();
+ //if (now!=0) { System.err.println(); System.err.println(System.currentTimeMillis()-now); now=0;}
+ long l = unBitSet(fp.readWord());
long l2 = expect.remove(0);
// FIXME, this is ugly and not size-independent
}
}
- public static void run(Fleet fleet, InputStream is) throws IOException {
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- byte[] buf = new byte[1024];
+ public static void run(Fleet fleet, Instruction[] instructions) throws IOException {
+ FleetProcess client = fleet.run(instructions);
while(true) {
- int numread = is.read(buf, 0, buf.length);
- if (numread==-1) break;
- baos.write(buf, 0, numread);
- }
- FleetProcess client = fleet.run(baos.toByteArray());
- while(true) {
- long result = client.readWord();
+ long result = unBitSet(client.readWord());
System.err.print(result);
System.err.print(" 0x");
System.err.print(Long.toString(result, 16));
}
}
+ public static long unBitSet(BitVector bs) {
+ long val = 0;
+ for(int i=0; i<37; i++) {
+ if (bs.get(i))
+ val |= (1L << i);
+ }
+ if ((val & (1L << 36)) != 0)
+ val = val | (0xffffffffffffffffL << 36);
+ return val;
+ }
+
static void usage() {
System.err.println(".........................................................................");
System.err.println("Fleet Framework UC Berkeley, Sun Labs / 2007");
--- /dev/null
+package edu.berkeley.fleet.api;
+
+/**
+ * A sequence of bits with a fixed length. This class performs
+ * important error-checking not found in the Java BitSet and
+ * BigInteger classes.
+ */
+public class BitVector {
+
+ private final boolean[] bits;
+
+ public BitVector(int length) {
+ this.bits = new boolean[length];
+ }
+
+ /** copy the low-order bits of the argument into this BitVector; returns this */
+ public BitVector set(long value) {
+ for(int i=0; i<length(); i++)
+ set(i, ((value >>> i) & 1L) != 0);
+ return this;
+ }
+
+ public int length() {
+ return bits.length;
+ }
+
+ public void set(int bit, boolean value) {
+ bits[bit] = value;
+ }
+
+ public boolean get(int bit) {
+ return bits[bit];
+ }
+
+ public String toString() {
+ StringBuffer ret = new StringBuffer();
+ ret.append(length()+"");
+ ret.append("'b");
+ for(int i=length()-1; i>=0; i--)
+ ret.append(get(i) ? '1' : '0');
+ return ret.toString();
+ }
+}
+
+
package edu.berkeley.fleet.api;
+/**
+ * A physical destination on the switch fabric -- may have multiple
+ * paths to it from any particular source.
+ */
public abstract class Destination {
- /** return the Ship to which this Pump belongs */
- public abstract Ship getShip();
+ private final Dock dock;
+
+ public Destination(Dock dock) {
+ this.dock = dock;
+ }
+
+ /** Get the Dock to which this destination belongs, null if none. */
+ public Dock getDock() { return dock; }
+
+ /** subclasses must override this */
+ public abstract String toString();
- /**
- * this returns the third component of the name; that is in
- * "ship.port.foo", it returns "foo", and in "ship.port" it
- * returns ""
- */
- public abstract String getDestinationName();
}
--- /dev/null
+package edu.berkeley.fleet.api;
+import java.util.*;
+
+/** A dock on a ship */
+public abstract class Dock {
+
+ private final Ship ship;
+
+ public Dock(Ship ship) {
+ this.ship = ship;
+ }
+
+ /** return the Ship to which this Dock belongs */
+ public Ship getShip() { return ship; }
+
+ /** the descriptive name of this dock (relative to its ship) */
+ public abstract String getName();
+
+ /** returns true if this is an input dock */
+ public abstract boolean isInputDock();
+
+ /** returns true if this is an output dock */
+ public abstract boolean isOutputDock();
+
+ /** returns the <tt>Path</tt> from this dock to <tt>dest</tt>, carrying the signal specified or none if null */
+ public abstract Path getPath(Destination dest, BitVector signal);
+
+ /** the data destination of this dock */
+ public abstract Destination getDataDestination();
+
+ /** the instruction destination of this dock */
+ public abstract Destination getInstructionDestination();
+
+ /**
+ * The maximum number of instructions we can put in the Dock
+ * instruction fifo, or Integer.MAX_VALUE if unbounded; note that
+ * this does not include the epilogue fifo -- that can be
+ * determined with getInstructionDestination().getFifoLength()
+ */
+ public abstract int getInstructionFifoSize();
+
+ public String toString() { return getShip()+"."+getName(); }
+}
package edu.berkeley.fleet.api;
-import edu.berkeley.fleet.doc.*;
import java.io.*;
import java.util.*;
+/**
+ * An instance of Fleet; each Fleet consists of a collection of
+ * <tt>Ship</tt>s.
+ *
+ * <p><b>Note about instruction representation:</b> it is very
+ * important to understand that the binary representation of an
+ * instruction includes a path from the dock which will
+ * <i>dispatch</i> the instruction to the dock which will
+ * <i>execute</i> the instruction. Therefore, an instruction cannot
+ * be converted <i>to</i> binary form without supplying a
+ * <i>dispatching dock</i> so the necessary path can be computed.
+ * <b>Moreover:</b> because a given string of bits uniquely describes
+ * a path only if given along with a starting point, instructions
+ * cannot be converted <i>from</i> binary format without knowing the
+ * dispatch dock from which they are meant to be dispatched. <i>This
+ * is why the {@link readInstruction} and {@link writeInstruction}
+ * methods take a "<tt>dispatchFrom</tt>" argument.</i>
+ */
public abstract class Fleet implements Iterable<Ship> {
- /** read a machine-formatted instruction from a file (into a Java object) */
- public abstract Instruction readInstruction(DataInputStream is) throws IOException;
-
- /** write a machine-formatted instruction to a file (from a Java object) */
- public abstract void writeInstruction(DataOutputStream os, Instruction instr) throws IOException;
-
- /** ships must be returned in the same order every time -- ordering may be significant */
public abstract Iterator<Ship> iterator();
- /** if possible, run the given code and create a FleetProcess */
- public FleetProcess run(byte[] code) {
- throw new RuntimeException("class " + this.getClass().getName() + " does not implement method run()");
- }
+ /** A ship is uniquely identified by its type (a string) and its ordinal; for example, Fifo[7]. */
+ public abstract Ship getShip(String type, int ordinal);
- /** extract the portion of ShipDescription which is specific to this fleet and generate any source code necessary */
- public void expand(ShipDescription sd) {
- throw new RuntimeException("class " + this.getClass().getName() + " does not implement method expand()");
- }
+ /** the natural word width of this machine */
+ public abstract int getWordWidth();
/**
- * This interface marks Fleets which can create ships on the fly, like the fleeterpreter;
- * if available, the parser will use this interface to create ships out of #ship definitions.
+ * Read a machine-formatted instruction from a file.
+ * @is The stream to read from.
+ * @dispatchFrom The dock from which the instructions being read are to be dispatched (required for decoding)
*/
- public static interface WithDynamicShips {
- public Ship createShip(String shiptype, String shipname);
- }
+ public abstract Instruction readInstruction(DataInputStream is, Dock dispatchFrom) throws IOException;
-}
\ No newline at end of file
+ /**
+ * Write a machine-formatted instruction to a file.
+ * @os The stream to write to.
+ * @dispatchFrom The dock from which the instruction being written is to be dispatched (required for encoding)
+ */
+ public abstract void writeInstruction(DataOutputStream os, Dock dispatchFrom, Instruction instr) throws IOException;
+
+ /** If supported, run the given code and create a FleetProcess to interact with it. */
+ public FleetProcess run(Instruction[] program) {
+ throw new RuntimeException("class " + this.getClass().getName() + " does not implement method run()");
+ }
+}
import java.io.*;
import java.util.*;
-/** represents a <i>running</i> "slave" fleet with a debug connection */
+/**
+ * Represents a <i>running</i> "slave" fleet with debugging
+ * facilities controlled by the "master" JVM.
+ *
+ * <p>Each Fleet which supports this API must include:
+ * <ul><li> The ability to dispatch instructions from the master, "on
+ * the fly".
+ * <li> A "debug.in" dock such that any words delivered there
+ * are sent back to the master.
+ * </ul>
+ */
public abstract class FleetProcess {
private boolean terminated = false;
- /** dumps an instruction into the fetch unit */
- public abstract void invokeInstruction(Instruction i);
+ /** dispatch an instruction */
+ public abstract void dispatchInstruction(Instruction i);
- /** reads a word back from the debug port */
- public abstract long readWord();
+ /** the dock used to read back data from the slave */
+ public abstract Dock getDebugInputDock();
- /** subclasses may be assured that this will be called exactly once */
+ /** returns the next word delivered at the dock specified by <tt>getDebugInputDock()</tt> */
+ public abstract BitVector readWord();
+
+ /** Terminate the process; subclasses may be assured that this will be called exactly once. */
protected abstract void _terminate();
public final synchronized void terminate() {
_terminate();
}
- public final boolean isTerminated() {
- return terminated;
- }
-
- public synchronized void finalize() {
- if (!terminated)
- terminate();
- }
-
+ public final boolean isTerminated() { return terminated; }
+ public synchronized void finalize() { terminate(); }
}
package edu.berkeley.fleet.api;
+import java.util.*;
+/** a Fleet instruction; includes execution location but not full dispatch path */
public abstract class Instruction {
- public final Pump pump;
- public Instruction(Pump pump) { this.pump = pump; }
- public String toString() { return pump+": "; }
+ /** the dock which is to execute this instruction */
+ public final Dock dock;
- public boolean isLooping() { return true; }
- public boolean isRepeating() { return false; }
- public boolean isSK() { return false; }
- public boolean isDL() { return false; }
+ /** true if the instruction is an outer-looping instruction */
+ public final boolean looping;
- public static class Clog extends Instruction {
- public Clog(Pump pump) { super(pump); }
- public String toString() { return super.toString() + "clog;"; }
- public boolean isLooping() { return false; }
- }
+ /** the instruction's predicate */
+ public final Predicate predicate;
- public static class UnClog extends Instruction {
- public UnClog(Pump pump) { super(pump); }
- public String toString() { return super.toString() + "unclog;"; }
+ Instruction(Dock dock, boolean looping, Predicate predicate) {
+ if (dock==null) throw new RuntimeException("dock may not be null");
+ if (predicate==null) throw new RuntimeException("predicate may not be null");
+ this.dock = dock;
+ this.looping = looping;
+ this.predicate = predicate;
}
- public static class Massacre extends Instruction {
- public Massacre(Pump pump) { super(pump); }
+ public String toString() {
+ String s = predicate.toString();
+ if (s.length()>0) s = "["+s+"] ";
+ return s+dock+": ";
}
- 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))+";"; }
- }
+ /**
+ * A <tt>set</tt> instruction.
+ *
+ * Note that immediates are supplied as Java <tt>long</tt> values
+ * because they are actual integers with two's complement
+ * sign-extension semantics. This is in contrast to most other
+ * immediate values in the API which are raw bit sequences of
+ * fixed length -- these are represented by instances of
+ * <tt>BitVector</tt>.
+ */
+ public static class Set extends Instruction {
- public static class PredicatedInstruction extends Instruction {
- public static final int P_ALWAYS = 0x0001;
- public static final int P_IF_A = 0x0002;
- public static final int P_IF_B = 0x0003;
- public static final int P_IF_Z = 0x0004;
-
- public final int predicate;
- public final boolean dl;
- public boolean isDL() { return dl; }
-
- public PredicatedInstruction(Pump pump, boolean dl, int predicate) {
- super(pump);
- this.predicate = predicate;
- this.dl = dl;
- }
- public String toString() {
- String dlx = dl ? "[dl] " : "";
- switch(predicate) {
- case P_ALWAYS: return dlx+ super.toString();
- case P_IF_A: return dlx+"[a] "+super.toString();
- case P_IF_B: return dlx+"[b] "+super.toString();
- case P_IF_Z: return dlx+"[z] "+super.toString();
+ /** the destination (latch to be set) */
+ public final SetDest dest;
+
+ /** the source (what will be put in the <tt>dest</tt> latch) */
+ public final SetSource source;
+
+ /** if <tt>source</tt> is <tt>Immediate</tt>, this is the immediate value; an integer */
+ public final long immediate;
+
+ /** if <tt>source</tt> is <tt>ImmediatePath</tt>, this is the immediate path */
+ public final Path path;
+
+ /** if <tt>dest</tt> is <tt>Flags</tt>, this is the truth table to update flag "a" */
+ public final FlagFunction newFlagA;
+
+ /** if <tt>dest</tt> is <tt>Flags</tt>, this is the truth table to update flag "b" */
+ public final FlagFunction newFlagB;
+
+ /** basic constructor */
+ public Set(Dock dock, boolean looping, Predicate predicate, SetDest dest, SetSource source) {
+ super(dock, looping, predicate);
+ OUTER: switch(dest) {
+ case InnerLoopCounter:
+ switch(source) {
+ case Infinity: case DataLatch: case Immediate: break OUTER;
+ default: break;
+ }
+ case OuterLoopCounter:
+ switch(source) {
+ case Decrement: case DataLatch: case Immediate: break OUTER;
+ default: break;
+ }
+ case DataLatch:
+ if (source==SetSource.Immediate) break;
+ default: throw new RuntimeException("cannot set " + dest + " to " + source);
}
- throw new Error();
+ this.source = source;
+ this.dest = dest;
+ this.immediate = 0;
+ this.path = null;
+ this.newFlagA = null;
+ this.newFlagB = null;
}
- }
- public static class SetFlags extends PredicatedInstruction {
- public static final int FLAG_Z = 0x0001;
- public static final int FLAG_NOT_Z = 0x0002;
- public static final int FLAG_S = 0x0004;
- public static final int FLAG_NOT_S = 0x0008;
- public static final int FLAG_B = 0x0010;
- public static final int FLAG_NOT_B = 0x0020;
- public static final int FLAG_A = 0x0040;
- public static final int FLAG_NOT_A = 0x0080;
-
- public final int flag_a;
- public final int flag_b;
- public SetFlags(Pump pump, boolean dl, int predicate, int flag_a, int flag_b) {
- super(pump, dl, predicate);
- this.flag_a = flag_a;
- this.flag_b = flag_b;
+ /** constructor for set instructions with immediates */
+ public Set(Dock dock, boolean looping, Predicate predicate, SetDest dest, long immediate) {
+ super(dock, looping, predicate);
+ if (dest!=SetDest.InnerLoopCounter && dest!=SetDest.OuterLoopCounter && dest!=SetDest.DataLatch)
+ throw new RuntimeException("a set instruction with dest="+dest+" may not take an immediate");
+ this.source = SetSource.Immediate;
+ this.dest = dest;
+ this.immediate = immediate;
+ this.path = null;
+ this.newFlagA = null;
+ this.newFlagB = null;
}
- public SetFlags(Pump pump, int flag_a, int flag_b) { this(pump, false, P_ALWAYS, flag_a, flag_b); }
-
- public boolean isLooping() { return true; }
- private String printFlag(int flag) {
- if (flag==0) return "0";
- if ((flag & (FLAG_Z | FLAG_NOT_Z)) == (FLAG_Z | FLAG_NOT_Z)) return "1";
- if ((flag & (FLAG_B | FLAG_NOT_B)) == (FLAG_B | FLAG_NOT_B)) return "1";
- if ((flag & (FLAG_A | FLAG_NOT_A)) == (FLAG_A | FLAG_NOT_A)) return "1";
- if ((flag & (FLAG_S | FLAG_NOT_S)) == (FLAG_S | FLAG_NOT_S)) return "1";
- String ret = "";
- if ((flag & FLAG_A) != 0) ret += (ret.length()>=0?"|":"") + "a";
- if ((flag & FLAG_NOT_A) != 0) ret += (ret.length()>=0?"|":"") + "!a";
- if ((flag & FLAG_B) != 0) ret += (ret.length()>=0?"|":"") + "b";
- if ((flag & FLAG_NOT_B) != 0) ret += (ret.length()>=0?"|":"") + "!b";
- if ((flag & FLAG_S) != 0) ret += (ret.length()>=0?"|":"") + "s";
- if ((flag & FLAG_NOT_S) != 0) ret += (ret.length()>=0?"|":"") + "!s";
- if ((flag & FLAG_Z) != 0) ret += (ret.length()>=0?"|":"") + "z";
- if ((flag & FLAG_NOT_Z) != 0) ret += (ret.length()>=0?"|":"") + "!z";
- return ret;
+
+ /** constructor for set instructions with immediate paths */
+ public Set(Dock dock, boolean looping, Predicate predicate, SetDest dest, Path path) {
+ super(dock, looping, predicate);
+ if (dest!=SetDest.TAPL)
+ throw new RuntimeException("a set instruction with dest="+dest+" may not take an immediate path");
+ this.source = SetSource.ImmediatePath;
+ this.dest = dest;
+ this.immediate = 0;
+ this.path = path;
+ this.newFlagA = null;
+ this.newFlagB = null;
}
- public String toString() {
- return super.toString() + " setflags a=" + printFlag(flag_a) + ", b=" + printFlag(flag_b);
+
+ /** constructor for <tt>set flags</tt> instructions */
+ public Set(Dock dock, boolean looping, Predicate predicate, FlagFunction newFlagA, FlagFunction newFlagB) {
+ super(dock, looping, predicate);
+ this.source = SetSource.Immediate;
+ this.dest = SetDest.Flags;
+ this.immediate = 0;
+ this.path = null;
+ this.newFlagA = newFlagA;
+ this.newFlagB = newFlagB;
}
- }
- public static class DecrLoop extends PredicatedInstruction {
- public DecrLoop(Pump pump) { super(pump, true, P_ALWAYS); }
- public DecrLoop(Pump pump, boolean dl, int predicate) { super(pump, dl, predicate); }
- public boolean isDL() { return true; }
- public boolean isLooping() { return true; }
- }
+ /** possible sources for the Set instruction */
+ public static enum SetSource {
+ Infinity, DataLatch, Immediate, ImmediatePath, Decrement;
+ }
+ /** possible destinations for the Set instruction */
+ public static enum SetDest {
+ InnerLoopCounter, OuterLoopCounter, TAPL, Flags, DataLatch;
+ }
- public static class Counter extends PredicatedInstruction {
- 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, false, P_ALWAYS, source, dest); }
- public Counter(Pump pump, boolean dl, int predicate, int source, int dest) {
- super(pump, dl, predicate);
- this.source = source;
- this.dest = dest;
+ /**
+ * (Immutable) a truth table describing how to update a flag
+ * based on the value of other flags; it is the logical OR of
+ * a set of flag predicates. This class is immutable; all
+ * methods that alter the function return a new object.
+ */
+ public static class FlagFunction implements Iterable<Predicate> {
+
+ /** the function that always assigns zero */
+ public static final FlagFunction ZERO = new FlagFunction();
+
+ /** the function that always assigns one */
+ public static final FlagFunction ONE = ZERO.add(Predicate.FlagA).add(Predicate.NotFlagA);
+
+ private final java.util.Set<Predicate> predicates;
+
+ public Iterator<Predicate> iterator() { return predicates.iterator(); }
+
+ private FlagFunction() { this(Collections.EMPTY_SET); }
+ private FlagFunction(java.util.Set<Predicate> set) { this.predicates = Collections.unmodifiableSet(set); }
+
+ /** returns the function which is the logical OR of this function and <tt>ff</tt> */
+ public FlagFunction add(FlagFunction ff) {
+ FlagFunction ret = this;
+ for(Predicate p : ff) ret = ret.add(p);
+ return ret;
+ }
+
+ /** returns the function which is the logical OR of this function and <tt>p</tt> */
+ public FlagFunction add(Predicate p) {
+ HashSet h = new HashSet();
+ h.addAll(predicates);
+ switch(p) {
+ case FlagA: case NotFlagA:
+ case FlagB: case NotFlagB:
+ case FlagC: case NotFlagC:
+ break;
+ default:
+ throw new RuntimeException("invalid predicate in FlagFunction: " + p);
+ }
+ h.add(p);
+ return new FlagFunction(h);
+ }
+
+ /** remove <tt>p</tt> from the set of terms which this function is the logical OR of */
+ public FlagFunction remove(Predicate p) {
+ HashSet h = new HashSet();
+ h.addAll(predicates);
+ h.remove(p);
+ return new FlagFunction(h);
+ }
+
+ public String toString() {
+ if (predicates.isEmpty()) return "0";
+ if (predicates.contains(Predicate.FlagA) && predicates.contains(Predicate.NotFlagA)) return "1";
+ if (predicates.contains(Predicate.FlagB) && predicates.contains(Predicate.NotFlagB)) return "1";
+ if (predicates.contains(Predicate.FlagC) && predicates.contains(Predicate.NotFlagC)) return "1";
+ StringBuffer ret = new StringBuffer();
+ boolean empty = true;
+ for(Predicate p : new Predicate[] {
+ Predicate.FlagA, Predicate.NotFlagA,
+ Predicate.FlagB, Predicate.NotFlagB,
+ Predicate.FlagC, Predicate.NotFlagC })
+ if (predicates.contains(p)) {
+ if (!empty) ret.append("| ");
+ ret.append(p);
+ empty = false;
+ }
+ return ret.toString();
+ }
}
+
public String toString() {
- if (source==LOOP_COUNTER && dest==DATA_LATCH) return "take loop counter;";
- StringBuffer ret = new StringBuffer();
- ret.append("load ");
switch(dest) {
- case LOOP_COUNTER: ret.append("loop"); break;
- case REPEAT_COUNTER: ret.append("repeat"); break;
- default: throw new RuntimeException("invalid");
- }
- ret.append(" counter");
- if (source == STANDING)
- ret.append(" with *");
- else if (source >= 0) {
- ret.append(" with " + source);
- } else if (source!=DATA_LATCH) {
- throw new RuntimeException("invalid");
+ case InnerLoopCounter:
+ switch(source) {
+ case Infinity: return super.toString()+"set ilc=*";
+ case DataLatch: return super.toString()+"set ilc=data";
+ case Immediate: return super.toString()+"set ilc="+immediate;
+ }
+ case OuterLoopCounter:
+ switch(source) {
+ case Decrement: return super.toString()+"set olc--";
+ case DataLatch: return super.toString()+"set olc=data";
+ case Immediate: return super.toString()+"set olc="+immediate;
+ }
+ case TAPL: return super.toString()+"set tapl="+path;
+ case Flags: return super.toString()+"set flags a="+newFlagA+" b="+newFlagB;
+ case DataLatch: return super.toString()+"set data="+immediate;
}
- ret.append(";");
- return ret.toString();
+ throw new Error("impossible");
}
- public boolean isLooping() { return true; }
}
- public static class Move extends PredicatedInstruction {
- public final Destination dest;
+ /** shifts an immediate into the low-order bits of the data latch */
+ public static class Shift extends Instruction {
+ public final BitVector immediate;
+ public Shift(Dock dock, boolean looping, Predicate predicate, BitVector immediate) {
+ super(dock, looping, predicate);
+ this.immediate = immediate;
+ }
+ public String toString() { return super.toString()+"shift "+immediate; }
+ }
+ /** all communication is performed with this instruction */
+ public static class Move extends Instruction {
+
+ /** if true, this instruction is vulnerable to torpedoes */
+ public final boolean interruptible;
+
+ /** if non-null, the path to load into the path latch */
+ public final Path path;
+
+ /** if true, a token will be consumed before execution */
public final boolean tokenIn;
+
+ /** if true, data will be consumed before execution */
public final boolean dataIn;
- public final boolean latch;
- public final boolean dataOutDest;
+
+ /** if true, the data consumed will be copied into the data latch */
+ public final boolean latchData;
+
+ /** if true, the data consumed will be copied into the path latch */
+ public final boolean latchPath;
+
+ /** if true, the value in the data latch will be transmitted (to the location in the path latch if at an output dock) */
public final boolean dataOut;
+
+ /** if true, the a token will be transmitted to the location in the path latch */
public final boolean tokenOut;
- public final boolean requeue;
- public final boolean ignoreUntilLast;
-
- /** count=0 denotes a standing move */
- public Move(Pump pump,
- boolean dl,
- int predicate,
- Destination dest,
+
+ public Move(Dock dock,
+ boolean looping,
+ Predicate predicate,
+ boolean interruptible,
+ Path path,
boolean tokenIn,
boolean dataIn,
- boolean latch,
- boolean dataOutDest,
+ boolean latchData,
+ boolean latchPath,
boolean dataOut,
- boolean tokenOut,
- boolean requeue,
- boolean ignoreUntilLast) {
- super(pump, dl, predicate);
- this.dest = dest;
+ boolean tokenOut
+ ) {
+ super(dock, looping, predicate);
+ this.path = path;
this.tokenIn = tokenIn;
this.dataIn = dataIn;
- this.latch = latch;
- this.dataOutDest = dataOutDest;
+ this.latchData = latchData;
+ this.latchPath = latchPath;
this.dataOut = dataOut;
this.tokenOut = tokenOut;
- this.requeue = requeue;
- this.ignoreUntilLast = ignoreUntilLast;
- 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 both \"sendto\" and \"notify\" on an outbox: " + this);
- if (latch && !dataIn)
- throw new RuntimeException("cannot have latch bit set without dataIn bit: " + this);
+ this.interruptible = interruptible;
+ if (dock != null && dock.isInputDock() && tokenIn && dataIn)
+ throw new RuntimeException("cannot have both \"wait\" and \"take\"/\"recieve\" on an input dock: " + this);
+ if (dock != null && dock.isOutputDock() && tokenOut && dataOut)
+ throw new RuntimeException("cannot have both \"sendto\" and \"notify\" on an output dock: " + this);
+ if (latchData && !dataIn)
+ throw new RuntimeException("cannot have latchData bit set without dataIn bit: " + this);
+ if (latchPath && !dataIn)
+ throw new RuntimeException("cannot have latchPath bit set without dataIn bit: " + this);
+ if (latchPath && path!=null)
+ throw new RuntimeException("cannot have latchPath and a non-null path: " + this);
}
public String toString() {
- // FIXME
- String ret = super.toString();
- boolean needcomma = false;
- if (tokenIn) { ret += (needcomma ? ", " : "") + "wait"; needcomma = true; }
- if (dataIn && latch) {
- if (pump.isInbox())
- ret += (needcomma ? ", " : "") + "receive";
- else
- ret += (needcomma ? ", " : "") + "take";
- needcomma = true;
- }
- if (dataIn && !latch) { ret += (needcomma ? ", " : "") + "dismiss"; needcomma = true; }
- if (dataOut) {
- if (pump.isInbox() || dest==null)
- ret += (needcomma ? ", " : "") + "deliver";
- else
- ret += (needcomma ? ", " : "") + "sendto "+dest;
- needcomma = true;
+ StringBuffer ret = new StringBuffer();
+ if (tokenIn) ret.append(", wait");
+ if (dataIn) {
+ if (latchPath) ret.append(dock.isInputDock() ? ", collect path" : ", recv path");
+ if (latchData) ret.append(dock.isInputDock() ? ", collect" : ", recv");
+ if (!latchPath && !latchData) ret.append(", discard");
}
- if (tokenOut) { ret += (needcomma ? ", " : "") + "notify "+dest; needcomma = true; }
- return ret;
- }
-
- public boolean isLooping() { return true; }
- public boolean isRepeating() { return true; }
- }
-
- public static class HalfLiteral extends PredicatedInstruction {
- public final long literal;
- public final boolean high;
- public HalfLiteral(Pump pump, boolean dl, int predicate, long literal, int count, boolean high) {
- super(pump, dl, predicate);
- this.literal = literal;
- this.high = high;
+ if (dataOut && dock.isInputDock()) ret.append(", deliver");
+ if (dataOut && !dock.isInputDock()) ret.append(path==null ? ", send" : "sendto " + path);
+ if (tokenOut) ret.append(path==null ? ", token" : "tokento " + path);
+ String s = ret.toString();
+ s = s.equals("") ? "nop" : s.substring(2);
+ if (interruptible) s = "[i] " + s;
+ return super.toString()+s;
}
- public boolean isRequeueing() { return true; }
- public boolean isLooping() { return true; }
}
- public static class Literal extends PredicatedInstruction {
- public final long literal;
- public Literal(Pump pump, boolean dl, int predicate, long literal) {
- super(pump, dl, predicate);
- this.literal = literal;
- }
- public boolean isLooping() { return true; }
- public boolean isRequeueing() { return true; }
- public static boolean canRepresent(long literal) {
- long il = literal;
- long allones = ~(-1L << 37);
- il = literal = literal & allones;
- if (((il & ~(-1L << 19)) & allones) == 0) return true;
- else if (((il | ~(-1L << 19)) & allones) == allones) return true;
- else if (((il & (-1L << 19)) & allones) == 0) return true;
- else if (((il | (-1L << 19)) & allones) == allones) return true;
- return false;
- }
- }
-
-
- public static class CodeBagDescriptor extends PredicatedInstruction {
- // address of CBD, relative to address that this instruction was loaded from
- public final long offset;
- public final long size;
- public CodeBagDescriptor(Pump pump, long offset, long size) { this(pump, false, P_ALWAYS, offset, size); }
- public CodeBagDescriptor(Pump pump, boolean dl, int predicate, long offset, long size) {
- super(pump, dl, predicate);
- this.offset = offset;
- this.size = size;
- }
- public String toString() {
- String off = ""+offset;
- if (offset > 0) off = "+"+off;
- return "(CBD @"+off+"+"+size+"): sendto " + pump;
- }
+ /** marks the end of a loop; closes the hatch */
+ public static class Tail extends Instruction {
+ public Tail(Dock dock) { super(dock, false, Predicate.IgnoreOLC); }
+ public String toString() { return super.toString() + "tail;"; }
}
}
--- /dev/null
+package edu.berkeley.fleet.api;
+import java.util.*;
+
+/**
+ * Represents a path through the switch fabric, from a Dock (source)
+ * to a Destination, plus an optional "signal" value.
+ */
+public abstract class Path {
+
+ /** The start of the path. */
+ public abstract Dock getSource();
+
+ /** The end of the path. */
+ public abstract Destination getDestination();
+
+ /** The number of units of buffering along this path. */
+ public abstract int getBufferingAmount();
+
+ /** A metric, in unspecified units, of the latency along this path; less is better. */
+ public abstract int getLatencyMetric();
+
+ /** An additional quantity of bits to be transmitted along with a packet, or null if none. */
+ public abstract BitVector getSignal();
+
+ public String toString() {
+ return getSource() + "->" + getDestination() + ((getSignal()==null||getSignal().length()==0)?"":(":"+getSignal()));
+ }
+
+}
--- /dev/null
+package edu.berkeley.fleet.api;
+
+/** possible predicate field values */
+public enum Predicate {
+ Default, FlagA, NotFlagA, FlagB, NotFlagB, FlagC, NotFlagC, IgnoreOLC;
+ public String toString() {
+ switch(this) {
+ case Default: return "";
+ case FlagA: return "a";
+ case FlagB: return "b";
+ case FlagC: return "c";
+ case NotFlagA: return "!a";
+ case NotFlagB: return "!b";
+ case NotFlagC: return "!c";
+ case IgnoreOLC: return "+";
+ default: throw new Error("unknown predicate " + this);
+ }
+ }
+}
+++ /dev/null
-package edu.berkeley.fleet.api;
-import java.util.*;
-
-public abstract class Pump {
-
- public Pump() { }
-
- /** the descriptive name of this pump (relative to its ship) */
- public abstract String getName();
-
- /** return the Ship to which this Pump belongs */
- public abstract Ship getShip();
-
- /** the maximum number of instructions we can put in the Pump instruction fifo,
- * or Integer.MAX_VALUE if unbounded */
- public abstract int getInstructionFifoLength();
-
- /** returns true if this is an inbox */
- public abstract boolean isInbox();
-
- /** returns true if this is an outbox */
- public abstract boolean isOutbox();
-
- /** get all destinations associated with this Pump; default implementation: just itself */
- public abstract Iterable<Destination> getDestinations();
-
- /** default implementation: the empty string */
- public String getDestinationName() { return ""; }
-
- /** return the Pump which is the destination of this Box's shortcut (if any) */
- public Pump getShortcut() { return null; }
-
- public abstract long resolveLiteral(String literal);
-}
package edu.berkeley.fleet.api;
-import java.io.*;
import java.util.*;
-public abstract class Ship {
+/** A ship in a Fleet; each ship consists of a collection of <tt>Dock</tt>s */
+public abstract class Ship implements Iterable<Dock> {
+
+ private final Fleet fleet;
+
+ public Ship(Fleet fleet) {
+ this.fleet = fleet;
+ }
/** return the Fleet that this Ship belongs to */
- public abstract Fleet getFleet();
+ public Fleet getFleet() { return fleet; }
- /** returns the type of the ship ("Fetch", "ALU", etc) */
+ /** returns the type of the ship ("Fetch", "Alu", etc) */
public abstract String getType();
- /** return all pumps which feed this ship; order is NOT significant */
- public abstract Iterable<Pump> getPumps();
-
- public Pump getPump(String s) {
- for(Pump b : getPumps())
- if (b.getName().equals(s))
- return b;
- throw new RuntimeException("unknown port \""+getType()+"."+s+"\"");
- }
+ public abstract Iterator<Dock> iterator();
- public int getOrdinal() {
- int ord = 0;
- for(Ship s : getFleet()) {
- if (s==this) return ord;
- if (s.getType() != null && s.getType().equals(getType())) ord++;
- }
- throw new RuntimeException("inconsistency: Ship does not belong to its own Fleet!");
- }
+ /** returns the dock on this ship having name "name" */
+ public abstract Dock getDock(String name);
+
+ /** the docks of a given type are numbered; this returns the ordinal number of this dock */
+ public abstract int getOrdinal();
public String toString() { return getType() + "[" + getOrdinal() + "]"; }
- public long resolveLiteral(String literal) {
- throw new RuntimeException("unknown literal \""+literal+"\" on ship "+this);
- }
}
--- /dev/null
+<body>
+<p>
+API for the FleetCode; see the class {@link edu.berkeley.fleet.api.Fleet} for a starting point and drill down from there.
+</p>
+
+<p>
+<b>Note:</b> all <tt>Instruction</tt> objects and their constituent parts
+(<tt>Path</tt>, <tt>Destination</tt>, etc) are immutable,
+like <tt>java.lang.String</tt>.
+</p>
+</body>
public class Main {
/** parse the assembly code on <tt>r</tt>, encode it for <tt>fleet</tt>, and write a binary on <tt>out</tt> */
- public static void assemble(Fleet fleet, Reader r, OutputStream out) throws Exception {
- new Parser(fleet).parse(r, out);
+ public static Instruction[] assemble(Fleet fleet, Reader r) throws Exception {
+ return new Parser(fleet).parse(r);
}
-}
\ No newline at end of file
+}
import edu.berkeley.sbp.meta.*;
import edu.berkeley.sbp.util.*;
import static edu.berkeley.fleet.util.BitManipulations.*;
-import static edu.berkeley.fleet.api.Instruction.SetFlags.*;
+import edu.berkeley.fleet.ies44.*;
+import edu.berkeley.fleet.api.Instruction.Set;
+import static edu.berkeley.fleet.api.Instruction.*;
+import static edu.berkeley.fleet.api.Instruction.Set.*;
+import static edu.berkeley.fleet.api.Predicate.*;
+import edu.berkeley.fleet.two.*;
+import edu.berkeley.fleet.fpga.*;
+import edu.berkeley.fleet.interpreter.*;
import java.util.*;
import java.io.*;
+
/**
* @author Adam Megacz <megacz@cs.berkeley.edu>
*/
public class Parser {
+ private static final BitVector SIGNAL_ZERO = new BitVector(1);
+ private static final BitVector SIGNAL_ONE = new BitVector(1);
+ static {
+ SIGNAL_ONE.set(0,true);
+ }
+
Parser(Fleet fleet) {
expect = new ArrayList<Long>();
this.fleet = fleet;
return grammar;
}
- Tree<String> parse(Reader r) throws Exception {
- return new CharParser(getGrammar()).parse(new CharInput(r)).expand1();
+ // FIXME: this ought to be cached via serialization, I think
+ private static CharParser cp = null;
+ Tree<String> parseIt(Reader r) throws Exception {
+ if (cp==null)
+ cp = new CharParser(getGrammar());
+ CharInput ci = new CharInput(r);
+ Forest f = cp.parse(ci);
+ return f.expand1();
}
- public void parse(Reader r, OutputStream out) throws Exception {
+ public Instruction[] parse(Reader r) throws Exception {
// this needs to be "code bag zero"
CodeBag baseCodeBag = new CodeBag();
CodeBag rootCodeBag = new CodeBag();
skip = false;
- baseCodeBag.add(new Instruction.CodeBagDescriptor(null, rootCodeBag.getFakeAddress(), 1));
- walk((Tree<String>)parse(r), rootCodeBag);
- if (fleet instanceof edu.berkeley.fleet.fpga.Fpga)
- ((edu.berkeley.fleet.fpga.Fpga)fleet).dumpFabric(true);
+ Dock dock = null;
+ if (fleet instanceof Fpga) {
+ dock = ((Fpga)fleet).getUniversalSource();
+ } else {
+ dock = ((Interpreter)fleet).getUniversalSource();
+ }
+ baseCodeBag.add(new Set(dock, false, IgnoreOLC, SetDest.DataLatch, (rootCodeBag.getFakeAddress())), true);
+ Tree<String> parsed = (Tree<String>)parseIt(r);
+ walk(parsed, rootCodeBag);
// map from arbitrary identifiers to actual addresses
int[] codeBagMap = new int[codeBags.size()];
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- DataOutputStream dos = new DataOutputStream(baos);
int count = 0;
for(int i=0; i<codeBags.size(); i++) {
CodeBag c = codeBags.get(i);
- dos.flush();
codeBagMap[i] = count;
for(Instruction inst : c) {
- fleet.writeInstruction(dos, inst);
count++;
}
}
// now write for real
- dos = new DataOutputStream(out);
count = 0;
+ ArrayList<Instruction> ret = new ArrayList<Instruction>();
for(int i=0; i<codeBags.size(); i++) {
CodeBag c = codeBags.get(i);
- dos.flush();
- for(Instruction inst : c) {
- if (inst instanceof Instruction.CodeBagDescriptor) {
- dos.flush();
- Instruction.CodeBagDescriptor old = (Instruction.CodeBagDescriptor)inst;
- int offset = codeBagMap[(int)old.offset];// - count;
- inst = new Instruction.CodeBagDescriptor(old.pump,
- offset,
- codeBags.get((int)old.offset).size());
+ for(int j=0; j<c.size(); j++) {
+ Instruction inst = c.get(j);
+ if (c.isCBD.contains(j)) {
+ Set old = (Set)inst;
+ long lit = 0;
+ lit = InstructionEncoder.CBD_SIZE.setval(lit, codeBags.get((int)old.immediate).size());
+ lit = InstructionEncoder.CBD_OFFSET.setval(lit, codeBagMap[(int)old.immediate]);
+ inst = new Set(old.dock, false, IgnoreOLC, SetDest.DataLatch, lit);
}
- fleet.writeInstruction(dos, inst);
+ ret.add(inst);
count++;
}
}
- dos.flush();
- out.flush();
- out.close();
+ return (Instruction[])ret.toArray(new Instruction[0]);
}
/** in the first pass, codebags are assigned "addresses" in arbitrary order */
String type = string(t.child(1));
Ship ship = null;
- if (fleet instanceof Fleet.WithDynamicShips) {
- Fleet.WithDynamicShips dyn = ((Fleet.WithDynamicShips)fleet);
+ if (fleet instanceof FleetWithDynamicShips) {
+ FleetWithDynamicShips dyn = ((FleetWithDynamicShips)fleet);
ship = dyn.createShip(type, name);
if (ship==null)
throw new RuntimeException("couldn't find a ship called \""+type+"\"");
} else if (head.equals("#include")) {
try {
- walk(parse(new InputStreamReader(new FileInputStream(string(t.child(0))))), cb);
+ walk(parseIt(new InputStreamReader(new FileInputStream(string(t.child(0))))), cb);
} catch (Exception e) {
throw new RuntimeException(e);
}
return string(t.child(0))+string(t.child(1));
}
- Destination portReference(Tree<String> t) {
- if (!"Pump".equals(t.head()) && !"Destination".equals(t.head()) && !"ShipSpecificLiteral".equals(t.head())) return null;
+ Path path(Dock dock, Tree<String> t) {
+ if (!"Dock".equals(t.head()) && !"Destination".equals(t.head()) && !"ShipSpecificLiteral".equals(t.head())) return null;
+ t = t.child(0);
String shipName = name(t.child(0));
String portName = name(t.child(1));
String subPort = t.size()<3 ? null : name(t.child(2));
Ship ship = shipMap.get(shipName);
if (ship==null) throw new RuntimeException("no such ship \""+shipName+"\"");
Destination ret = null;
- Pump bb = null;
- for(Pump b : ship.getPumps())
+ Dock bb = null;
+ for(Dock b : ship)
if (b.getName().equals(portName)) {
bb = b;
}
if (bb==null)
throw new RuntimeException("no such pump \""+portName+"\"");
if (subPort==null) subPort="";
- for(Destination d : bb.getDestinations())
- if (d.getDestinationName().equals(subPort))
- return d;
- if (ret==null)
- throw new RuntimeException("no such pump \""+portName+"\" on ships of type \""+ship.getType()+"\"");
- return ret;
+ if (":i".equals(t.head())) return dock.getPath(bb.getInstructionDestination(),SIGNAL_ZERO);
+ if (":1".equals(t.head())) return dock.getPath(bb.getDataDestination(),SIGNAL_ONE);
+ if (":0".equals(t.head())) return dock.getPath(bb.getDataDestination(),SIGNAL_ZERO);
+ return dock.getPath(bb.getDataDestination(),SIGNAL_ZERO);
}
- Pump pump(Tree<String> t) {
- if (!"Pump".equals(t.head()) && !"Destination".equals(t.head()) && !"ShipSpecificLiteral".equals(t.head()))
+ Dock dock(Tree<String> t) {
+ if (!"Dock".equals(t.head()) && !"Destination".equals(t.head()) && !"ShipSpecificLiteral".equals(t.head()))
throw new RuntimeException(t+"");
String shipName = name(t.child(0));
String portName = name(t.child(1));
Ship ship = shipMap.get(shipName);
if (ship==null) throw new RuntimeException("no such ship \""+shipName+"\"");
- Pump bb = null;
- for(Pump b : ship.getPumps())
+ Dock bb = null;
+ for(Dock b : ship)
if (b.getName().equals(portName))
return b;
throw new RuntimeException("no such pump \""+portName+"\"");
break;
}
}
- Pump chosenport = chosenship.getPump(portName);
+ if (chosenship==null) throw new RuntimeException("no ships of type " + shipType);
+ Dock chosenport = chosenship.getDock(portName);
Tree specs = t.child(2);
long literal = 0;
for(int i=0; i<specs.size(); i++) {
Tree tt = specs.child(i);
- literal |= chosenport.resolveLiteral(stringBody(tt));
+ literal |= resolveLiteral(chosenport, stringBody(tt));
}
return literal;
}
- private static int parseFlags(Tree<String> t) {
- int ret = 0;
+ private static long resolveLiteral(Dock dd, String s) {
+ long val = 0;
+ long ret = 0;
+ boolean hasval = false;
+ if (s.indexOf('=') != -1) {
+ val = Long.parseLong(s.substring(s.indexOf('=')+1));
+ s = s.substring(0, s.indexOf('='));
+ hasval = true;
+ }
+ ShipDescription.Constant c = ((FleetTwoDock)dd).getConstant(s);
+ if (c==null) throw new RuntimeException("no constant " + s + " on dock " + dd);
+ ret |= c.setbits;
+ ret &= ~c.clearbits;
+ if (hasval)
+ ret |= ((~(0xffffffffffffffffL << c.numberWidth)) & val) << c.numberOffset;
+ return ret;
+ }
+
+ private static FlagFunction parseFlags(Tree<String> t) {
+ FlagFunction ret = FlagFunction.ZERO;
for(int i=0; i<t.size(); i++) {
String s = t.child(i).head();
- if (s.equals("0")) continue;
- if (s.equals("1")) { ret |= (FLAG_A | FLAG_NOT_A); }
- if (s.equals("a")) ret |= FLAG_A;
- if (s.equals("!a")) ret |= FLAG_NOT_A;
- if (s.equals("b")) ret |= FLAG_B;
- if (s.equals("!b")) ret |= FLAG_NOT_B;
- if (s.equals("z")) ret |= FLAG_Z;
- if (s.equals("!z")) ret |= FLAG_NOT_Z;
- if (s.equals("s")) ret |= FLAG_S;
- if (s.equals("!s")) ret |= FLAG_NOT_S;
+ if (s.equals("0")) ret = ret.add(FlagFunction.ZERO);
+ if (s.equals("1")) ret = ret.add(FlagFunction.ONE);
+ if (s.equals("a")) ret = ret.add(FlagA);
+ if (s.equals("!a")) ret = ret.add(NotFlagA);
+ if (s.equals("b")) ret = ret.add(FlagB);
+ if (s.equals("!b")) ret = ret.add(NotFlagB);
+ if (s.equals("c")) ret = ret.add(FlagC);
+ if (s.equals("!c")) ret = ret.add(NotFlagC);
}
return ret;
}
fillCodeBag(statement, cb2);
} else if (t.head().equals("Fiber")) {
- Pump pump = (Pump)pump(t.child(0));
+ Dock dock = (Dock)dock(t.child(0));
OUTER: for(Tree tt : t.child(1)) {
int count = 1;
- int predicate = Instruction.PredicatedInstruction.P_ALWAYS;
- boolean dl = false;
- if ("[dl]".equals(tt.child(0).head())) dl = true;
- if ("[a]".equals(tt.child(1).head())) predicate = Instruction.PredicatedInstruction.P_IF_A;
- if ("[b]".equals(tt.child(1).head())) predicate = Instruction.PredicatedInstruction.P_IF_B;
- if ("[z]".equals(tt.child(1).head())) predicate = Instruction.PredicatedInstruction.P_IF_Z;
- tt = tt.child(2);
- if ("unclog".equals(tt.head())) {
- cb.add(new Instruction.UnClog(pump));
- continue;
- } else if ("clog".equals(tt.head())) {
- cb.add(new Instruction.Clog(pump));
- continue;
- } else if ("kill".equals(tt.head())) {
- count = tt.size()==0 ? 1 : (int)number(tt.child(0));
- cb.add(new Instruction.Kill(pump, count));
+ Predicate predicate = Default;
+ boolean looping = false;
+ boolean interruptible = false;
+ for(int i=0; i<tt.child(0).size(); i++) {
+ Tree ttt = tt.child(0).child(i);
+ if ("[a]".equals(ttt.head())) predicate = FlagA;
+ if ("[b]".equals(ttt.head())) predicate = FlagB;
+ if ("[c]".equals(ttt.head())) predicate = FlagC;
+ if ("[!a]".equals(ttt.head())) predicate = NotFlagA;
+ if ("[!b]".equals(ttt.head())) predicate = NotFlagB;
+ if ("[!c]".equals(ttt.head())) predicate = NotFlagC;
+ if ("[+]".equals(ttt.head())) predicate = IgnoreOLC;
+ if ("[I]".equals(ttt.head())) interruptible = true;
+ if ("[L]".equals(ttt.head())) looping = true;
+ }
+ tt = tt.child(1);
+ if ("tail".equals(tt.head())) {
+ cb.add(new Tail(dock));
continue;
} else if ("setflags".equals(tt.head())) {
- cb.add(new Instruction.SetFlags(pump, dl, predicate, parseFlags(tt.child(0)), parseFlags(tt.child(1))));
+ cb.add(new Set(dock, looping, predicate, parseFlags(tt.child(0)), parseFlags(tt.child(1))));
continue;
- } else if ("loop".equals(tt.head())) {
- cb.add(new Instruction.Counter(pump, dl, predicate, Instruction.Counter.LOOP_COUNTER, Instruction.Counter.DATA_LATCH));
+ } else if ("tapl".equals(tt.head())) {
+ cb.add(new Set(dock, looping, predicate, SetDest.TAPL, path(dock, tt.child(0))));
continue;
} else if ("load".equals(tt.head()) && "loop".equals(tt.child(0).head())) {
- cb.add(new Instruction.Counter(pump, dl, predicate, Instruction.Counter.DATA_LATCH, Instruction.Counter.LOOP_COUNTER));
+ cb.add(new Set(dock, looping, predicate, SetDest.OuterLoopCounter, SetSource.DataLatch));
continue;
} else if ("load".equals(tt.head()) && "repeat".equals(tt.child(0).head())) {
- cb.add(new Instruction.Counter(pump, dl, predicate, Instruction.Counter.DATA_LATCH, Instruction.Counter.REPEAT_COUNTER));
+ cb.add(new Set(dock, looping, predicate, SetDest.InnerLoopCounter, SetSource.DataLatch));
continue;
} else if ("*".equals(tt.head())) {
- cb.add(new Instruction.Counter(pump, dl, predicate, Instruction.Counter.STANDING, Instruction.Counter.REPEAT_COUNTER));
+ cb.add(new Set(dock, looping, predicate, SetDest.InnerLoopCounter, SetSource.Infinity));
continue;
} else if ("with".equals(tt.head()) && "loop".equals(tt.child(0).head())) {
- cb.add(new Instruction.Counter(pump, dl, predicate, (int)number(tt.child(1)), Instruction.Counter.LOOP_COUNTER));
+ cb.add(new Set(dock, looping, predicate, SetDest.OuterLoopCounter, (number(tt.child(1)))));
continue;
} else if ("with".equals(tt.head()) && "repeat".equals(tt.child(0).head())) {
- cb.add(new Instruction.Counter(pump, dl, predicate, (int)number(tt.child(1)), Instruction.Counter.REPEAT_COUNTER));
- continue;
- } else if ("massacre".equals(tt.head())) {
- cb.add(new Instruction.Massacre(pump));
+ cb.add(new Set(dock, looping, predicate, SetDest.InnerLoopCounter, (number(tt.child(1)))));
continue;
} else if ("decrement".equals(tt.head())) {
- cb.add(new Instruction.DecrLoop(pump));
+ cb.add(new Set(dock, looping, predicate, SetDest.OuterLoopCounter, SetSource.Decrement));
continue;
} else if ("literal".equals(tt.head())) {
long literal = 0;
CodeBag cb2 = getCodeBag("anon"+(anoncount++));
for(Tree<String> statement : tq.child(0))
fillCodeBag(statement, cb2);
- cb.add(new Instruction.CodeBagDescriptor(pump, dl, predicate, cb2.getFakeAddress(), 0));
+ cb.add(new Set(dock, looping, predicate, SetDest.DataLatch, (cb2.getFakeAddress())), true);
continue OUTER;
} else if (tt.child(0).head().equals("Name")) {
String refname = name(tt.child(0));
CodeBag cb2 = getCodeBag(refname);
- cb.add(new Instruction.CodeBagDescriptor(pump, dl, predicate, cb2.getFakeAddress(), 0));
+ cb.add(new Set(dock, looping, predicate, SetDest.DataLatch, (cb2.getFakeAddress())), true);
continue OUTER;
} else if (tt.child(0).head().equals("[")) {
literal = parseSSL(tt.child(0));
count = 0;
}
- if (Instruction.Literal.canRepresent(literal)) {
- cb.add(new Instruction.Literal(pump, dl, predicate, literal));
+
+ if (InstructionEncoder.isSmallEnoughToFit(literal)) {
+ cb.add(new Set(dock, looping, predicate, SetDest.DataLatch, (literal)));
} else {
- cb.add(new Instruction.HalfLiteral(pump, dl, predicate, getField(36, 19, literal), count, true));
- cb.add(new Instruction.HalfLiteral(pump, dl, predicate, getField(18, 0, literal), count, false));
+ // FIXME bitwidth hardwired!
+ cb.add(new Shift(dock, looping, predicate, new BitVector(37).set(getField(36, 19, literal))));
+ cb.add(new Shift(dock, looping, predicate, new BitVector(37).set(getField(18, 0, literal))));
}
+
continue;
}
Tree ttx = null;
}
tt = tt.child(0);
if (tt.head().equals("[*]")) {
- cb.add(new Instruction.Counter(pump, dl, predicate, Instruction.Counter.STANDING, Instruction.Counter.REPEAT_COUNTER));
+ cb.add(new Set(dock, looping, predicate, SetDest.InnerLoopCounter, SetSource.Infinity));
//count = 0;
requeue = false;
} else if (tt.head().equals("int")) {
boolean latch = false;
boolean dataOut = false;
boolean tokenOut = false;
- boolean dataOutDest = false;
+ boolean dispatch = false;
boolean localLiteral = false;
boolean ignoreUntilLast = false;
long literal = 0;
- Destination dest = null;
+ Path path = null;
for(int i=0; i<ttx.size(); i++) {
Tree ttt = ttx.child(i);
if ("wait".equals(ttt.head())) { tokenIn = true; }
else if ("nop".equals(ttt.head())) { }
- else if ("kill".equals(ttt.head())) {
- cb.add(new Instruction.Kill(pump, 1));
- continue OUTER;
- }
else if ("discard".equals(ttt.head())) { dataIn = true; latch = false; }
else if ("take".equals(ttt.head())) { dataIn = true; latch = true; }
+ else if ("recv".equals(ttt.head())) { dataIn = true; latch = true; }
+ else if ("collect".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; dataOut = true; }
- else if ("sendto".equals(ttt.head())) { dataOut = true; dest = portReference(ttt.child(0)); }
+ else if ("send".equals(ttt.head())) { dispatch = true; dataOut = true; }
+ else if ("sendto".equals(ttt.head())) { dataOut = true; path = path(dock, ttt.child(0)); }
else if ("deliver".equals(ttt.head())) { dataOut = true; }
- else if ("notify".equals(ttt.head())) { tokenOut = true; dest = portReference(ttt.child(0)); }
- else if ("notifyLast".equals(ttt.head())) { tokenOut = true; ignoreUntilLast = true; dest = portReference(ttt.child(0)); }
+ else if ("notify".equals(ttt.head())) { tokenOut = true; path = path(dock, ttt.child(0)); }
+ else if ("notifyLast".equals(ttt.head())) { tokenOut = true; ignoreUntilLast = true; path = path(dock, ttt.child(0)); }
}
- cb.add(new Instruction.Move(pump, dl, predicate,
- dest, tokenIn, dataIn,
- latch, dataOutDest, dataOut, tokenOut, requeue, ignoreUntilLast));
+ cb.add(new Move(dock, looping, predicate,
+ interruptible, path, tokenIn, dataIn,
+ latch, dispatch, dataOut, tokenOut));
}
}
}
private class CodeBag extends ArrayList<Instruction> {
public long address = -1;
public final String name;
+ private HashSet<Integer> isCBD = new HashSet<Integer>();
public CodeBag() { codeBags.add(this); this.name = "root"; }
public CodeBag(String name) { codeBags.add(this); codeBagsByName.put(name, this); this.name = name; }
public long getFakeAddress() { return codeBags.indexOf(this); }
public boolean equals(Object o) { return this==o; }
+ public void add(Instruction i, boolean isCBD) {
+ if (isCBD) this.isCBD.add(size());
+ add(i);
+ }
}
// hideous hack
if (negative) val = -1L * val;
return val;
}
+ /**
+ * This interface marks Fleets which can create ships on the fly, like the fleeterpreter;
+ * if available, the parser will use this interface to create ships out of #ship definitions.
+ */
+ public static interface FleetWithDynamicShips {
+ public Ship createShip(String shiptype, String shipname);
+ }
}
Directives:: = Directive */ ws
CodeBagBody:: = (Fiber | CodeBagDef) */ ws
CodeBagDef:: = CodeBagName ":" "{" CodeBagBody "}" /ws
-Fiber:: = Pump ":" Instructions /ws
+Fiber:: = Dock ":" Instructions /ws
-// FIXME: should not have predicates on clog/unclog/kill/massacre
+// FIXME: should not have predicates on tail/untail/kill/massacre
Instructions:: = Instruction +/ ws
-Instruction:: = DL Predicate InstructionX
-DL = "" | ^"[dl]" ws
-Predicate = "" | ^"[a]" ws | ^"[b]" ws | ^"[z]" ws
-InstructionX = ^"unclog" ";" /ws
- | ^"clog" ";" /ws
- | ^"massacre" ";" /ws
- | ^"kill" ";" /ws
+Instruction:: = (Tags:: Tag*) InstructionX
+Tag = ^"[a]" ws | ^"[b]" ws | ^"[c]" ws
+ | ^"[!a]" ws | ^"[!b]" ws | ^"[!c]" ws
+ | ^"[+]" ws
+ | ^"[I]" ws
+ | ^"[L]" ws
+InstructionX = ^"tail" ";" /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
+ | "load" ^"tapl" "with" Destination ";" /ws
| ^"decrement" "loop" "counter" ";" /ws
| ^"setflags" "a" "=" Flags "," "b" "=" Flags ";" /ws
- | ^"kill" int ";" /ws
| ^"literal" Literal RequeueCount ";" /ws
| RepeatCount Commands RequeueCount ^";" /ws
RepeatCount = "" | ^"[*]" | "[" int "]"
| ^"1"
| ^"a"
| ^"b"
- | ^"s"
- | ^"z"
+ | ^"c"
| ^"!a"
| ^"!b"
- | ^"!s"
- | ^"!z"
+ | ^"!c"
Commands:: = Command +/ (ws "," ws)
Command = ^"wait"
| ^"nop"
| ^"discard"
| ^"recieve"
+ | ^"recv"
| ^"take"
+ | ^"collect"
| ^"deliver"
| ^"send"
| ^"sendto" Destination /ws
| ^"notifyLast" Destination /ws
Literal = int
- | ShipType "." PortName ^"[" Constants "]"
+ | ShipType "." DockName ^"[" Constants "]"
| CodeBagName
| "{" CodeBagBody "}" /ws
-Pump:: = ShipName "." PortName
-Destination:: = ShipName "." PortName
+Dock:: = ShipName "." DockName
+Destination:: = (ShipName ^"." DockName)
+ | (ShipName "." DockName ^":i")
+ | (ShipName "." DockName ^":0")
+ | (ShipName "." DockName ^":1")
Constants:: = Constant +/ ","
Constant:: = [a-zA-Z0-9=_\-]++
CodeBagName = UpcaseWord
ShipType = UpcaseWord
ShipName = DowncaseWord
-PortName = DowncaseWord
+DockName = DowncaseWord
Word = UpcaseWord | DowncaseWord
UpcaseWord = Name:: [A-Z] ("":: [A-Za-z0-9_]**)
DowncaseWord = Name:: [a-z] ("":: [A-Za-z0-9_]**)
+++ /dev/null
-package edu.berkeley.fleet.doc;
-
-import java.io.*;
-import java.util.*;
-
-public class Constant {
-
- long setbits = 0;
- long clearbits = 0;
- boolean signExtend = false;
- int numberOffset = 0;
- int numberWidth = 0;
-
- public Constant(String s) {
- if (s.startsWith("0x")) {
- setbits = Long.parseLong(s.substring(2), 16);
- clearbits = ~setbits;
- } else if (s.length() == 37) {
- for(int i=36; i>=0; i--) {
- char c = s.charAt(36-i);
- switch(c) {
- case '0': clearbits |= (1<<i); break;
- case '1': setbits |= (1<<i); break;
- case '.': break;
- case 's': signExtend = true; numberOffset = i; numberWidth++; break;
- case 'u': signExtend = false; numberOffset = i; numberWidth++; break;
- }
- }
- } else {
- setbits = Long.parseLong(s);
- clearbits = ~setbits;
- }
- }
-
-
-}
\ No newline at end of file
+++ /dev/null
-package edu.berkeley.fleet.doc;
-
-import java.io.*;
-import java.util.*;
-
-
-public class Doc {
-
- public static void print() throws Exception {
- if (!new File(".tmp").exists())
- new File(".tmp").mkdirs();
- PrintWriter pw = new PrintWriter(new FileOutputStream(".tmp/FleetTwo.Manual.tex"));
- BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("doc/archman.tex")));
- for(String s = br.readLine(); s!=null; s = br.readLine())
- pw.println(s);
- for(String f : new File("ships").list()) {
- print(pw, new ShipDescription(f, new BufferedReader(new InputStreamReader(new FileInputStream(new File("ships/"+f))))));
- }
- pw.println("\\end{document}");
- pw.close();
- }
-
- private static void print(PrintWriter pw, ShipDescription sd) throws Exception {
- pw.println("\\pagebreak");
- pw.println("\\section*{The {\\tt "+sd.getName()+"} Ship}");
- pw.println("\\addcontentsline{toc}{subsection}{"+sd.getName()+"}");
- String tex = sd.getSection("tex");
- /*
- for(PumpDescription bbd : sd) {
- pw.println("{\\bf "+(bbd.isInbox() ? "Input: " : "Output: ")+"{\\tt "+bbd.getName()+"}}\n\n");
- }
- */
- int boxGap = 5;
- int boxHeight = 25;
- int boxWidth = 75;
-
- int leftSize = 0;
- int rightSize = 0;
- for(PumpDescription bbd : sd)
- if (bbd.isLeft()) leftSize += (boxHeight+boxGap);
- else rightSize += (boxHeight+boxGap);
-
- int totalHeight = Math.max(leftSize, rightSize);
- int shipWidth = (int)(boxWidth * 1.5);
- int totalWidth = boxGap*2 + boxWidth*2 + shipWidth;
-
- pw.println("");
- pw.println("\\begin{center}");
- pw.println("\\begin{empfile}["+sd.getName()+"]");
- pw.println("\\begin{emp}["+sd.getName()+"]("+(totalWidth+10)+","+(totalHeight+10)+")");
- pw.println(" beginfig(1)");
- pw.println(" pickup pencircle scaled 1pt;");
- pw.println(" draw "+
- "("+((totalWidth-shipWidth)/2)+","+0+")--"+
- "("+((totalWidth-shipWidth)/2)+","+totalHeight+")--"+
- "("+(totalWidth-((totalWidth-shipWidth)/2))+","+totalHeight+")--"+
- "("+(totalWidth-((totalWidth-shipWidth)/2))+","+0+")--"+
- "("+((totalWidth-shipWidth)/2)+","+0+");");
- int left = 0;
- int right = 0;
- for(PumpDescription bbd : sd) {
- int ypos = (totalHeight - (boxGap/2) - (bbd.isLeft() ? left : right));
- int half = (totalWidth-shipWidth)/2;
- int p1 = bbd.isLeft() ? (half-5) : ((totalWidth-half)+5);
- int p3 = bbd.isLeft() ? (p1 - boxWidth) : (p1 + boxWidth);
- if (bbd.isInbox()) {
- int p1x = p1;
- p1 = p3;
- p3 = p1x;
- }
- boolean goo = ((bbd.isLeft() && bbd.isInbox()) || (!bbd.isLeft() && bbd.isOutbox()));
- int p2 = goo ? (p3 - (boxHeight/2)) : (p3 + (boxHeight/2));
- if (bbd.isLeft()) left += (boxHeight+boxGap);
- else right += (boxHeight+boxGap);
- if (goo) {
- pw.println(" label.rt(btex \\tt "+bbd.getName()+" etex, ("+(p1+3)+","+(ypos-boxHeight/2)+"));");
- } else {
- pw.println(" label.lft(btex \\tt "+bbd.getName()+" etex, ("+(p1-3)+","+(ypos-boxHeight/2)+"));");
- }
- pw.println(" draw "+
- " ("+p1+","+ypos+")--"+
- " ("+p2+","+ypos+")--"+
- " ("+p3+","+(ypos-(boxHeight/2))+")--"+
- " ("+p2+","+(ypos-boxHeight)+")--"+
- " ("+p1+","+(ypos-boxHeight)+")--"+
- " ("+p1+","+ypos+");");
- if (bbd.isLeft()) leftSize += boxHeight;
- else rightSize += boxHeight;
- }
- pw.println(" endfig;");
- pw.println("\\end{emp}");
- pw.println("\\end{empfile}");
- pw.println("\\end{center}");
- pw.println("");
-
- if (tex!=null)
- pw.println(tex);
- }
-
-}
\ No newline at end of file
+++ /dev/null
-package edu.berkeley.fleet.doc;
-
-import java.io.*;
-import java.util.*;
-
-public class PumpDescription implements Iterable<String> {
-
- public String getName() { return name; }
- public boolean isInbox() { return inbox; }
- public boolean isOutbox() { return !inbox; }
- public boolean isLeft() { return left; }
- public boolean tokensOnly() { return tokenOnly; }
- public String getShortcut() { return shortcut; }
- public Iterator<String> iterator() { return destinations.iterator(); }
-
- // private //////////////////////////////////////////////////////////////////////////////
-
- private final ShipDescription ship;
- private final String shortcut;
- private final String name;
- private final boolean inbox;
- private final boolean tokenOnly;
- private final boolean left;
- private ArrayList<String> destinations = new ArrayList<String>();
-
- // FIXME
- public HashMap<String,Constant> constants = new HashMap<String,Constant>();
-
- PumpDescription(ShipDescription ship, String name, boolean tokenOnly, boolean left, boolean inbox) {
- this(ship, name, tokenOnly, inbox, left, null);
- }
- PumpDescription(ShipDescription ship, String name, boolean tokenOnly, boolean left, boolean inbox, String shortcut) {
- this.left = left;
- this.ship = ship;
- this.name = name;
- this.inbox = inbox;
- this.tokenOnly = tokenOnly;
- this.shortcut = shortcut;
- ship.add(this);
- }
-
- void addDest(String dest) { destinations.add(dest); }
-
- public Constant getConstant(String name) {
- Constant ret = constants.get(name);
- if (ret == null) ret = ship.getConstant(name);
- return ret;
- }
-
- public long resolveLiteral(String s) {
- long val = 0;
- long ret = 0;
- boolean hasval = false;
- if (s.indexOf('=') != -1) {
- val = Long.parseLong(s.substring(s.indexOf('=')+1));
- s = s.substring(0, s.indexOf('='));
- hasval = true;
- }
- Constant c = getConstant(s);
- if (c==null) throw new RuntimeException("no constant " + s + " on pump " + this);
- ret |= c.setbits;
- ret &= ~c.clearbits;
- if (hasval)
- ret |= ((~(0xffffffffffffffffL << c.numberWidth)) & val) << c.numberOffset;
- return ret;
- }
-}
+++ /dev/null
-package edu.berkeley.fleet.doc;
-
-import java.io.*;
-import java.util.*;
-
-/** the Java representation of a .ship file */
-public class ShipDescription implements Iterable<PumpDescription> {
-
- public String getName() { return name; }
- public String getSection(String sectionName) { return sections.get(sectionName); }
- public Iterator<PumpDescription> iterator() { return pumps.iterator(); }
-
- public ShipDescription(String name, BufferedReader r) throws IOException {
- if (name.endsWith(".ship"))
- name = name.substring(0, name.length() - ".ship".length());
- while(name.indexOf('/') != -1) name = name.substring(name.indexOf('/')+1);
- this.name = name;
- String sectionName = null;
- StringBuffer sb = new StringBuffer();
- while(true) {
- String s = r.readLine();
- if (s==null || s.startsWith("==")) {
- if (sectionName != null) sections.put(sectionName, sb.toString());
- if (s==null) break;
- sb = new StringBuffer();
- sectionName = s.trim();
- while(sectionName.startsWith("="))
- sectionName = sectionName.substring(1);
- while(sectionName.endsWith("="))
- sectionName = sectionName.substring(0, sectionName.length()-1);
- sectionName = sectionName.trim().toLowerCase();
- continue;
- }
- sb.append(s+"\n");
- }
- for(String s : sections.keySet())
- processSection(s);
- }
-
- // private //////////////////////////////////////////////////////////////////////////////
-
- private String name;
- private String texDocumentation;
-
- // must keep proper ordering for FPGA (FIXME: should alphabetize when synthesizing)
- private ArrayList<PumpDescription> pumps = new ArrayList<PumpDescription>();
-
- private HashMap<String,String> sections = new HashMap<String,String>();
-
- // FIXME
- public HashMap<String,Constant> constants = new HashMap<String,Constant>();
-
- public Constant getConstant(String name) {
- return constants.get(name);
- }
-
- private void processSection(String section) throws IOException {
- if (section.equals("")) {
- BufferedReader br = new BufferedReader(new StringReader(sections.get(section)));
- for(String s = br.readLine(); s != null; s = br.readLine()) {
- if (s.trim().length()==0) continue;
- String key = s.substring(0, s.indexOf(':')).trim();
- String val = s.substring(s.indexOf(':')+1).trim();
- if (key.toLowerCase().equals("ship"))
- name = val.trim();
- }
- } else if (section.equals("constants")) {
- BufferedReader br = new BufferedReader(new StringReader(sections.get(section)));
- for(String s = br.readLine(); s != null; s = br.readLine()) {
- if (s.indexOf(':')==-1) continue;
- String key = s.substring(0, s.indexOf(':')).trim();
- if (key.startsWith("constant")) {
- String constname = key.substring("constant".length()+1).trim();
- String val = s.substring(s.indexOf(':')+1).trim();
- constants.put(constname, new Constant(val));
- }
- }
- } else if (section.equals("ports")) {
- BufferedReader br = new BufferedReader(new StringReader(sections.get(section)));
- boolean rightSide = false;
- PumpDescription p = null;
- for(String s = br.readLine(); s != null; s = br.readLine()) {
- if (s.trim().length()==0) { rightSide = true; continue; }
-
- String key = s.substring(0, s.indexOf(':')).trim();
- boolean tokenOnly = false;
- boolean inbox = false;
- key = key.replaceAll(" +", " ");
- if (key.equals("token in")) { tokenOnly = true; inbox = true; }
- else if (key.equals("token out")) { tokenOnly = true; inbox = false; }
- else if (key.equals("data in")) { tokenOnly = false; inbox = true; }
- else if (key.equals("data out")) { tokenOnly = false; inbox = false; }
- else if (key.equals("in")) { tokenOnly = false; inbox = true; }
- else if (key.equals("out")) { tokenOnly = false; inbox = false; }
- else if (key.startsWith("constant")) {
- String constname = key.substring("constant".length()+1).trim();
- String val = s.substring(s.indexOf(':')+1).trim();
- p.constants.put(constname, new Constant(val));
- continue;
- } else if (key.startsWith("shortcut to")) {
- continue;
- }
- else throw new RuntimeException("unknown port type: \""+key+"\"");
-
- p = null;
- String val = s.substring(s.indexOf(':')+1).trim();
- String boxname = val.indexOf('.') != -1 ? val.substring(0, val.indexOf('.')) : val;
- String dest = val.indexOf('.') != -1 ? val.substring(val.indexOf('.')+1) : "";
- for (PumpDescription b : pumps)
- if (b.getName().equals(boxname)) { p = b; break; }
- if (p==null) p = new PumpDescription(this, boxname, tokenOnly, inbox, !rightSide);
- p.addDest(dest);
- }
- }
- }
-
- void add(PumpDescription b) { pumps.add(b); }
-}
\ No newline at end of file
package edu.berkeley.fleet.fpga;
+import static edu.berkeley.fleet.util.BitManipulations.*;
import edu.berkeley.fleet.api.*;
import java.io.*;
import java.net.*;
import java.util.*;
import java.util.concurrent.*;
+import static edu.berkeley.fleet.api.Instruction.Set.*;
+import static edu.berkeley.fleet.api.Predicate.*;
+import static edu.berkeley.fleet.api.Instruction.*;
+
public class Client extends FleetProcess {
private Socket s;
- private BlockingQueue<Long> queue = new LinkedBlockingQueue<Long>();
+ private BlockingQueue<BitVector> queue = new LinkedBlockingQueue<BitVector>();
public void invokeInstruction(Instruction i) {
throw new RuntimeException("not implemented");
return val;
}
- public long readWord() {
+ public Dock getDebugInputDock() {
+ throw new RuntimeException();
+ }
+ public BitVector readWord() {
if (isTerminated())
throw new RuntimeException("this fleet has been terminated");
try {
- return signExtend(queue.take());
+ return queue.take();
} catch (InterruptedException e) { throw new RuntimeException(e); }
}
} catch (Exception e) { e.printStackTrace(); }
}
- public Client(String bitfile, byte[] program) throws IOException {
+ public Client(String bitfile, byte[] program) throws Exception {
s = new Socket(InetAddress.getByName("goliath.megacz.com"), 3133);
- OutputStream os = s.getOutputStream();
+ OutputStream os = new BufferedOutputStream(s.getOutputStream());
PrintWriter pw = new PrintWriter(new OutputStreamWriter(os));
pw.print(Server.pass_string+" "+bitfile+"\n");
pw.flush();
- int numinstrs = (program.length / 6);
- os.write((numinstrs >> (5*8)) & 0xff);
- os.write((numinstrs >> (4*8)) & 0xff);
- os.write((numinstrs >> (3*8)) & 0xff);
- os.write((numinstrs >> (2*8)) & 0xff);
- os.write((numinstrs >> (1*8)) & 0xff);
- os.write((numinstrs >> (0*8)) & 0xff);
+
+ Fpga fpga = new Fpga();
+ ByteArrayOutputStream newp = new ByteArrayOutputStream();
+ DataOutputStream newpd = new DataOutputStream(newp);
+ long startcbd = 0;
+
+ Dock inAddrWrite = null;
+ Dock inDataWrite = null;
+ Dock inCBD = null;
+ Dock out = null;
+ Dock debugIn = null;
+ Dock ihorn = null;
+
+ for(Ship ship : fpga) {
+ if ("Memory".equals(ship.getType()) && ship.getOrdinal()==0) {
+ inAddrWrite = ship.getDock("inAddrWrite");
+ inDataWrite = ship.getDock("inDataWrite");
+ inCBD = ship.getDock("inCBD");
+ out = ship.getDock("out");
+ ihorn = ship.getDock("outIhorn");
+ }
+ if ("Debug".equals(ship.getType()) && ship.getOrdinal()==0) {
+ debugIn = ship.getDock("in");
+ }
+ }
+
+ for(int i=0; i<program.length; i+=6) {
+ long lit = 0
+ | ((program[i+0] & 0xffL) << 40)
+ | ((program[i+1] & 0xffL) << 32)
+ | ((program[i+2] & 0xffL) << 24)
+ | ((program[i+3] & 0xffL) << 16)
+ | ((program[i+4] & 0xffL) << 8)
+ | ((program[i+5] & 0xffL) << 0);
+ Instruction inst = fpga.readInstruction(fpga.getUniversalSource(), lit);
+ if (i==0) {
+ long offset = (lit >> 6) & ~(-1L << 10);
+ long size = (lit >> 0) & ~(-1L << 6);
+ startcbd = (offset << 6) | size;
+ size = 0;
+ offset = 0;
+ inst = new Instruction.Shift(fpga.getUniversalSource(), false, IgnoreOLC, new BitVector(fpga.getWordWidth()).set(0));
+ } else {
+ if (fpga.writeInstruction(fpga.getUniversalSource(), inst) != lit)
+ throw new RuntimeException("no match: " + inst + " @"+(i/6)+"\n"+Long.toString(lit,16)+
+ "\n"+Long.toString(fpga.writeInstruction(fpga.getUniversalSource(), inst),16));
+ }
+ //fpga.writeInstruction(newpd, fpga.getUniversalSource(), inst);
+ }
+
+ for(int i=0; i<program.length; i+=6) {
+ long lit = 0
+ | ((program[i+0] & 0xffL) << 40)
+ | ((program[i+1] & 0xffL) << 32)
+ | ((program[i+2] & 0xffL) << 24)
+ | ((program[i+3] & 0xffL) << 16)
+ | ((program[i+4] & 0xffL) << 8)
+ | ((program[i+5] & 0xffL) << 0);
+ fpga.writeInstruction(newpd, fpga.getUniversalSource(), discard(out));
+ fpga.writeInstruction(newpd, fpga.getUniversalSource(), new Instruction.Shift(inDataWrite, false, IgnoreOLC, new BitVector(fpga.getWordWidth()).set(getField(36, 19, lit))));
+ fpga.writeInstruction(newpd, fpga.getUniversalSource(), new Instruction.Shift(inDataWrite, false, IgnoreOLC, new BitVector(fpga.getWordWidth()).set(getField(18, 0, lit))));
+ fpga.writeInstruction(newpd, fpga.getUniversalSource(), deliver(inDataWrite));
+ fpga.writeInstruction(newpd, fpga.getUniversalSource(), new Instruction.Shift(inAddrWrite, false, IgnoreOLC, new BitVector(fpga.getWordWidth()).set(getField(36, 19, i/6))));
+ fpga.writeInstruction(newpd, fpga.getUniversalSource(), new Instruction.Shift(inAddrWrite, false, IgnoreOLC, new BitVector(fpga.getWordWidth()).set(getField(18, 0, i/6))));
+ fpga.writeInstruction(newpd, fpga.getUniversalSource(), deliver(inAddrWrite));
+ }
+ fpga.writeInstruction(newpd, fpga.getUniversalSource(), new Instruction.Shift(inCBD, false, IgnoreOLC, new BitVector(fpga.getWordWidth()).set(getField(36, 19, startcbd))));
+ fpga.writeInstruction(newpd, fpga.getUniversalSource(), new Instruction.Shift(inCBD, false, IgnoreOLC, new BitVector(fpga.getWordWidth()).set(getField(18, 0, startcbd))));
+ fpga.writeInstruction(newpd, fpga.getUniversalSource(), wait(inCBD));
+ fpga.writeInstruction(newpd, fpga.getUniversalSource(), deliver(inCBD));
+ fpga.writeInstruction(newpd, fpga.getUniversalSource(), sendto(out, out.getPath(inCBD.getDataDestination(),null)));
+ fpga.writeInstruction(newpd, fpga.getUniversalSource(), new Instruction.Set(ihorn, false, IgnoreOLC, SetDest.InnerLoopCounter, SetSource.Infinity));
+ fpga.writeInstruction(newpd, fpga.getUniversalSource(),
+ new Instruction.Move(ihorn, false, IgnoreOLC, false, null,false,true,true,true,true,false));
+
+ newpd.flush();
+ program = newp.toByteArray();
+
os.write(program);
os.flush();
- final InputStream is = s.getInputStream();
+ final InputStream is = new BufferedInputStream(s.getInputStream());
new Thread() {
public void run() {
try {
result |= val2;
}
if (val==-1) break;
- queue.put(result);
+ BitVector bs = new BitVector(37);
+ for(int i=0; i<37; i++)
+ bs.set(i, ((result >> i) & 1L)!=0);
+ queue.put(bs);
}
} catch (SocketException e) {
} catch (Exception e) { throw new RuntimeException(e);
}
}.start();
}
-
+ /*
public static void main(String[] args) throws Exception {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buf = new byte[1024];
System.err.println();
}
}
-}
\ No newline at end of file
+ */
+ public void dispatchInstruction(Instruction i) { throw new RuntimeException(); }
+ private static Move discard(Dock dock) { return new Move(dock, false, IgnoreOLC, false, null, false, true, false, false, false, false); }
+ private static Move deliver(Dock dock) { return new Move(dock, false, IgnoreOLC, false, null, false, false, false, false, true, false); }
+ private static Move wait(Dock dock) { return new Move(dock, false, IgnoreOLC, false, null, true, false, false, false, false, false); }
+ private static Move sendto(Dock dock, Path path) { return new Move(dock, false, IgnoreOLC, false, path, false, false, false, false, true, false); }
+}
--- /dev/null
+package edu.berkeley.fleet.fpga;
+import edu.berkeley.fleet.api.*;
+import edu.berkeley.fleet.ies44.*;
+import edu.berkeley.fleet.*;
+import java.lang.reflect.*;
+import edu.berkeley.sbp.chr.*;
+import edu.berkeley.sbp.misc.*;
+import edu.berkeley.sbp.meta.*;
+import edu.berkeley.sbp.util.*;
+import java.util.*;
+import java.io.*;
+import static edu.berkeley.fleet.ies44.InstructionEncoder.*;
+import static edu.berkeley.fleet.verilog.Verilog.*;
+
+
+public interface FabricElement {
+
+ public FpgaPath getPath(FabricElement dest, BitVector signal);
+
+ public void addInput(FabricElement in, Module.Port inPort);
+ public void addOutput(FabricElement out, Module.Port outPort);
+
+ public Module.Port getOutputPort();
+ public Module.Port getInputPort();
+}
--- /dev/null
+package edu.berkeley.fleet.fpga;
+import edu.berkeley.fleet.api.*;
+import edu.berkeley.fleet.ies44.*;
+import edu.berkeley.fleet.*;
+import java.lang.reflect.*;
+import edu.berkeley.sbp.chr.*;
+import edu.berkeley.sbp.misc.*;
+import edu.berkeley.sbp.meta.*;
+import edu.berkeley.sbp.util.*;
+import java.util.*;
+import java.io.*;
+import static edu.berkeley.fleet.ies44.InstructionEncoder.*;
+import static edu.berkeley.fleet.verilog.Verilog.*;
+
+public class FifoModule extends Module {
+ public FifoModule(int len) {
+ super("fifo"+len);
+ Module.SourcePort in = createInputPort("in", WIDTH_PACKET);
+ Module.SinkPort out = createOutputPort("out", WIDTH_PACKET, "");
+ Module.InstantiatedModule[] stages = new Module.InstantiatedModule[len];
+ if (len==0) {
+ new Event(new Object[] { in, out },
+ new Action[] { in, out, new AssignAction(out, in) });
+ } else {
+ Module fifo0 = new FifoModule(0);
+ for(int i=0; i<=len; i++) {
+ if (i<len) stages[i] = new Module.InstantiatedModule(this, fifo0);
+ Module.SourcePort driver = i==0 ? in : stages[i-1].getOutputPort("out");
+ Module.SinkPort driven = i==len ? out : stages[i].getInputPort("in");
+ driver.connect(driven);
+ }
+ }
+ }
+}
package edu.berkeley.fleet.fpga;
import edu.berkeley.fleet.fpga.*;
-import edu.berkeley.fleet.doc.*;
import edu.berkeley.fleet.api.*;
import edu.berkeley.fleet.ies44.*;
import edu.berkeley.fleet.*;
import edu.berkeley.sbp.util.*;
import java.util.*;
import java.io.*;
+import edu.berkeley.fleet.two.*;
+import static edu.berkeley.fleet.ies44.InstructionEncoder.*;
+import static edu.berkeley.fleet.verilog.Verilog.*;
-public class Fpga extends Fleet {
- public ArrayList<FpgaShip> shiplist = new ArrayList<FpgaShip>();
- public HashMap<String,FpgaShip> ships = new HashMap<String,FpgaShip>();
- public Iterator<Ship> iterator() { return (Iterator<Ship>)(Object)shiplist.iterator(); }
+public class Fpga extends Fleet {
- private String bitfile;
+ public Ship getShip(String type, int ordinal) {
+ for(Ship s : this)
+ if (s.getType().equals(type))
+ if (ordinal-- < 0)
+ return s;
+ return null;
+ }
- public static void main(String[] s) throws Exception {
- new Fpga().dumpFabric(false);
+ public int getWordWidth() { return 37; }
+ private static final BitVector SIGNAL_ZERO = new BitVector(1);
+ private static final BitVector SIGNAL_ONE = new BitVector(1);
+ static {
+ SIGNAL_ONE.set(0,true);
}
- public Fpga() { this("gaspified.bit"); }
- public Fpga(String bitfile) {
- this.bitfile = bitfile;
- createShip("Debug", "debug");
- createShip("Memory", "memory");
- createShip("Memory", "memory2"); // need this to avoid a bug
+ public Module top;
+ public FabricElement top_horn;
- createShip("Fifo", "fifo1");
- createShip("Fifo", "fifo2");
- createShip("Alu2", "alu2a");
- createShip("BitFifo", "bitfifo");
- createShip("Rotator", "rotator");
- // above is the minimal ship set needed to run the regression suite, excluding "ships" tests
- createShip("Alu1", "alu1");
- createShip("Lut3", "lut3");
- createShip("Alu3", "alu3");
+ public LinkedHashMap<String,FpgaShip> ships = new LinkedHashMap<String,FpgaShip>();
+ public Iterator<Ship> iterator() { return (Iterator<Ship>)(Object)ships.values().iterator(); }
- /*
- createShip("Stack", "Stack");
- createShip("Fifo", "fifo3");
- createShip("Choice", "Choice");
- */
- // above is the minimal ship set needed to run the regression suite, including "ships" tests
-
- // below are extra bonus ships
- /*
- createShip("Alu2", "alu2b");
- createShip("Alu2", "alu2c");
- createShip("Alu2", "alu2d");
- createShip("Fifo", "fifo4");
- createShip("Memory", "Memory");
- createShip("Choice", "Choice");
- createShip("Choice", "Choice");
- createShip("Choice", "Choice");
- */
- dumpFabric(true);
- }
+ public static void main(String[] s) throws Exception {
+ String prefix = s[0];
- public Ship createShip(String type, String name) {
- try {
- ShipDescription sd = new ShipDescription(name, new BufferedReader(new InputStreamReader(new FileInputStream("ships/"+type+".ship"))));
- FpgaShip ship = new FpgaShip(this, name, type, sd);
- ships.put(name, ship);
- shiplist.add(ship);
- return ship;
- } catch (IOException e) { throw new RuntimeException(e); }
+ new FunnelModule().dump(prefix);
+ new HornModule().dump(prefix);
+
+ new FifoModule(0).dump(prefix);
+ new FifoModule(4).dump(prefix);
+ new FifoModule(8).dump(prefix);
+ new FpgaDock.DockModule(false).dump(prefix);
+ new FpgaDock.DockModule(true).dump(prefix);
+
+ Module top = new Module("root");
+ new Fpga(top).top.dump(prefix);
}
- public FleetProcess run(final byte[] instructions) {
+ public FleetProcess run(Instruction[] instructions) {
try {
- return new Client(bitfile, instructions);
- } catch (IOException e) { throw new RuntimeException(e); }
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ DataOutputStream dos = new DataOutputStream(baos);
+ for(Instruction i : instructions)
+ writeInstruction(dos, getUniversalSource(), i);
+ dos.flush();
+ return new Client("none", baos.toByteArray());
+ } catch (Exception e) { throw new RuntimeException(e); }
}
- public void dumpFabric(boolean quiet) {
- // FIXME: this is really ugly: the order of port declarations in
- // the XXXShip.java file must match the order in the .balsa file!
-
- ArrayList instructionports = new ArrayList<FpgaPump>();
- for(FpgaShip ship : shiplist)
- for(Pump port : ship.getPumps())
- if (!((FpgaPump)port).special())
- instructionports.add(port);
- FabricTree instructions =
- new FabricTree((FpgaPump[])instructionports.toArray(new FpgaPump[0]),
- "ihorn",
- "instruction");
-
- ArrayList inputports = new ArrayList<FpgaPump>();
- for(FpgaShip ship : shiplist)
- for(Pump port : ship.getPumps())
- if (!((FpgaPump)port).special())
- inputports.add(port);
- FabricTree inputs =
- new FabricTree((FpgaPump[])inputports.toArray(new FpgaPump[0]),
- "horn",
- "dest");
-
- ArrayList outputports = new ArrayList<FpgaPump>();
- for(FpgaShip ship : shiplist)
- for(Pump port : ship.getPumps())
- if (!((FpgaPump)port).special() || ((FpgaPump)port).dhorn())
- outputports.add(port);
- FabricTree outputs =
- new FabricTree((FpgaPump[])outputports.toArray(new FpgaPump[0]),
- "funnel",
- "source");
-
- ArrayList ihornports = new ArrayList<FpgaPump>();
- for(FpgaShip ship : shiplist)
- for(Pump port : ship.getPumps())
- if (((FpgaPump)port).ihorn())
- ihornports.add(port);
- FabricTree ihorns =
- new FabricTree((FpgaPump[])ihornports.toArray(new FpgaPump[0]),
- "funnel",
- "ihorn");
-
- if (quiet) return;
- System.out.println("`include \"macros.v\"");
- System.out.println("module fabric(clk, rst, data_Memory0_command_r, data_Memory0_command_a, data_Memory0_command,");
- System.out.println(" data_Debug0_out_r, data_Debug0_out_a, data_Debug0_out);");
- System.out.println(" input clk;");
- System.out.println(" input rst;");
- System.out.println(" input data_Memory0_command_r;");
- System.out.println(" output data_Memory0_command_a;");
- System.out.println(" output data_Debug0_out_r;");
- System.out.println(" input data_Debug0_out_a;");
- System.out.println(" output [(`PACKET_WIDTH-1):0] data_Debug0_out;");
- System.out.println(" input [(`PACKET_WIDTH-1):0] data_Memory0_command;");
- //System.out.println(" wire [(`INSTRUCTION_WIDTH-1):0] data_Memory0_ihorn;");
- //System.out.println(" wire [(`PACKET_WIDTH-1):0] data_Memory0_dhorn;");
- System.out.println();
-
- System.out.println();
-
- instructions.dumpChannels(true);
- outputs.dumpChannels(true);
- inputs.dumpChannels(true);
- ihorns.dumpChannels(true);
- for(FpgaShip ship : shiplist)
- for(Pump port : ship.getPumps())
- if (!((FpgaPump)port).special() || ((FpgaPump)port).dhorn())
- System.out.println(" wire [(`PACKET_WIDTH-1):0] data_"
- +getUniqueName(ship)+"_"+port.getName()+";");
-
- System.out.println("wire [(`PACKET_WIDTH-1):0] ihornleft;");
-
- System.out.println("");
- instructions.dumpChannels(false);
- System.out.println("");
- outputs.dumpChannels(false);
- System.out.println("");
- inputs.dumpChannels(false);
- System.out.println("");
- ihorns.dumpChannels(false);
- System.out.println("");
- for(FpgaShip ship : shiplist) {
- System.out.print(ship.getType().toLowerCase());
- System.out.print(" ");
- System.out.print("krunk"+(krunk++));
- System.out.print("(clk, rst, ");
- boolean first = true;
- for(Pump port : ship.getPumps()) {
- if (!first) System.out.print(", ");
- first = false;
- String prefix = "data_";
- if (((FpgaPump)port).ihorn()) prefix = "ihorn_";
- if (((FpgaPump)port).dhorn()) prefix = "source_";
- System.out.print(prefix+getUniqueName(port.getShip())+"_"+port.getName()+"_r, ");
- System.out.print(prefix+getUniqueName(port.getShip())+"_"+port.getName()+"_a, ");
- System.out.print(prefix+getUniqueName(port.getShip())+"_"+port.getName());
- System.out.print(" ");
- }
- System.out.println(");");
-
- for(Pump port : ship.getPumps()) {
- if (((FpgaPump)port).special()) continue;
- if (((FpgaPump)port).inbox) {
- System.out.print("inbox");
- } else {
- System.out.print("outbox");
- }
- System.out.print(" krunk"+(krunk++)+"(clk, rst, ");
- System.out.print("instruction_"+getUniqueName(port.getShip())+"_"+port.getName()+"_r, ");
- System.out.print("instruction_"+getUniqueName(port.getShip())+"_"+port.getName()+"_a, ");
- System.out.print("`packet_data(instruction_"+getUniqueName(port.getShip())+"_"+port.getName()+"), ");
- System.out.print("dest_"+getUniqueName(port.getShip())+"_"+port.getName()+"_r, ");
- System.out.print("dest_"+getUniqueName(port.getShip())+"_"+port.getName()+"_a, ");
- System.out.print("dest_"+getUniqueName(port.getShip())+"_"+port.getName()+", ");
- System.out.print("source_"+getUniqueName(port.getShip())+"_"+port.getName()+"_r, ");
- System.out.print("source_"+getUniqueName(port.getShip())+"_"+port.getName()+"_a, ");
- System.out.print("source_"+getUniqueName(port.getShip())+"_"+port.getName()+", ");
- System.out.print("data_"+getUniqueName(port.getShip())+"_"+port.getName()+"_r, ");
- System.out.print("data_"+getUniqueName(port.getShip())+"_"+port.getName()+"_a, ");
- System.out.print("data_"+getUniqueName(port.getShip())+"_"+port.getName());
- System.out.print(");");
- System.out.println();
- }
-
- }
+ // Setup //////////////////////////////////////////////////////////////////////////////
- System.out.println("funnel ihornfun(clk, rst, "+
- " ihornleft_r, ihornleft_a, ihornleft,"+
- " ihorn_r, ihorn_a, ihorn,"+
- " source_r, source_a, source);");
- System.out.println("horn tophorn(clk, rst, "+
- " ihornleft_r, ihornleft_a, ihornleft,"+
- " instruction_r, instruction_a, instruction,"+
- " dest_r, dest_a, dest);");
- /*
- System.out.println("assign instruction_r = ihorn_r;");
- System.out.println("assign ihorn_a = instruction_a;");
- System.out.println("assign instruction = ihorn;");
- System.out.println("assign dest_r = source_r;");
- System.out.println("assign source_a = dest_a;");
- System.out.println("assign dest = source;");
- */
- System.out.println("endmodule");
+ public Ship createShip(String type, String name) throws IOException {
+ ShipDescription sd = new ShipDescription(type, new BufferedReader(new InputStreamReader(new FileInputStream("ships/"+type+".ship"))));
+ FpgaShip ship = new FpgaShip(this, sd);
+ ships.put(name, ship);
+ return ship;
}
- private static class FabricTree {
- int master_idx = 1;
- String prefix;
- Node root;
- public void dumpChannels(boolean decl) { root.dumpChannels(0, decl); }
- public FabricTree(FpgaPump[] ports, String component, String prefix) {
- this.prefix = prefix;
- root = (Node)mkNode("", component, ports, 0, ports.length, 0, 0);
- }
- private Object mkNode(String name, String component, FpgaPump[] ports,
- int start, int end, int addr, int bits) {
- if (end-start == 0) return null;
- if (end-start == 1) {
- FpgaPump p = ports[start];
- if (prefix.equals("instruction")) {
- p.instr_addr = (addr<<1);
- p.instr_bits = bits+1;
- } else if (prefix.equals("dest")) {
- p.addr = (addr << 1) | 1;
- p.bits = bits+1;
- if (bits >= 11)
- throw new RuntimeException("too many pumps!");
- int count = 0;
- for(Destination d : p.getDestinations()) {
- if (!(d instanceof FpgaPump.VirtualPort)) continue;
- FpgaPump.VirtualPort vp = (FpgaPump.VirtualPort)d;
- vp.addr = p.addr | (count << bits);
- count++;
- }
- }
- return p;
- }
- int len = end-start;
- int count = 0;
- int count2 = 0;
- int breakpt = 0;
- if (end-start <= 2) {
- breakpt = (start+end)/2;
- } else {
- for(int i=start; i<end; i++)
- count += count(ports[i].getDestinations());
- for(int i=start; i<end-1; i++) {
- count2 += count(ports[i].getDestinations());
- breakpt = i;
- if (i>start && count2 >= count/2) break;
- }
- }
- return new Node(name,
- component,
- mkNode(name+"_0", component, ports, start, breakpt, addr, bits+1),
- mkNode(name+"_1", component, ports, breakpt, end, addr | (1 << bits), bits+1),
- addr,
- bits);
+ public Fpga() throws Exception { this(new Module("root")); }
+ public Fpga(Module top) throws Exception {
+ this.top = top;
+ debugShip = createShip("Debug", "debug");
+ createShip("Memory", "memory");
+ createShip("Fifo", "fifo1");
+ createShip("Fifo", "fifo2");
+ createShip("Alu2", "alu2a");
+ createShip("Rotator", "rotator");
+ //createShip("Alu1", "alu1");
+ createShip("Lut3", "lut3");
+ createShip("Alu3", "alu3");
+
+ Module fifostage = new FifoModule(0);
+ Module fifo4 = new FifoModule(4);
+ Module fifo8 = new FifoModule(8);
+ Module horn = new HornModule();
+ Module funnel = new FunnelModule();
+ Module outbox = new FpgaDock.DockModule(false);
+ Module inbox = new FpgaDock.DockModule(true);
+
+ Module.SinkPort debug_in = top.createWirePort("debug_in", WIDTH_PACKET);
+ Module.SourcePort debug_out = null;
+ for(FpgaShip ship : (Iterable<FpgaShip>)(Object)this) {
+ if (ship.getType().toLowerCase().equals("debug"))
+ debug_out = ship.getVerilogModule().getOutputPort("debug_out");
}
- private String describe(String prefix, Object o) {
- if (o==null) return null;
- if (o instanceof FpgaPump) {
- FpgaPump p = (FpgaPump)o;
- return prefix+"_"+getUniqueName(p.getShip())+"_"+p.getName();
- }
- if (o instanceof Node) {
- return ((Node)o).describe(prefix);
+
+ Module.SourcePort in = top.createInputPort("in", 8);
+ Module.SinkPort out = top.createOutputPort("out", 8, "");
+ Module.Latch temp_in = top.new Latch("temp", WIDTH_PACKET) { public String doReset() { return name+"=0;"; } };
+ Module.Latch count = top.new Latch("count", 8);
+ Module.Latch count_out = top.new Latch("count_out", 8);
+ top.new Event(new Object[] { in, debug_in },
+ new Object[] { new SimpleAction(temp_in.getVerilogName()+" = ("+temp_in.getVerilogName()+" << 8) | in;"),
+ new SimpleAction("if (count >= 5) begin"+
+ " count <= 0; "+
+ " `packet_token("+debug_in.getVerilogName()+") <= 0;"+
+ " `packet_data("+debug_in.getVerilogName()+") <= "+temp_in.getVerilogName()+";"+
+ " `packet_dest("+debug_in.getVerilogName()+") <= `instruction_dest("+temp_in.getVerilogName()+");"+
+ " "+debug_in.getVerilogName()+"_r <= 1; "+
+ "end else count <= count+1; "),
+ in
+ });
+ top.new Event(new Object[] { out, debug_out },
+ new Object[] { new SimpleAction(out.getVerilogName()+" <= ("+debug_out.getVerilogName()+">> (count_out*8));"),
+ new SimpleAction("if (count_out >= 5) begin "+
+ "count_out <= 0; "+debug_out.getVerilogName()+"_a <= 1; end"+
+ " else count_out <= count_out+1; "),
+ out });
+
+ ArrayList sources = new ArrayList<FabricElement>();
+ ArrayList dests = new ArrayList<FabricElement>();
+ for(FpgaShip ship : (Iterable<FpgaShip>)(Object)this) {
+ if (ship.getType().toLowerCase().equals("debug"))
+ debug_out = ship.getVerilogModule().getOutputPort("debug_out");
+ for(Dock port : ship) {
+ sources.add(((FpgaDock)port));
+ dests.add(port.getInstructionDestination());
+ dests.add(port.getDataDestination());
}
- return null;
}
- private class Node {
- Object left;
- Object right;
- String name;
- String component;
- int addr;
- int bits;
- public Node(String name, String component, Object left, Object right, int addr, int bits) {
- this.left = left;
- this.right = right;
- this.name = name;
- this.component = component;
- this.addr = addr;
- this.bits = bits;
- }
- public void dumpChannels(int indentamount, boolean decl) {
- String indent = "";
- for(int i=0; i<indentamount; i++) indent += " ";
- if (decl) {
- String n = describe(prefix).startsWith("instruction")
- ? "[(`PACKET_WIDTH-1):0]" : "[(`PACKET_WIDTH-1):0]";
- System.out.println(" wire "+n+" "+indent+describe(prefix)+";");
- } else {
- System.out.println(" "+indent+
- component+" "+
- "krunk"+(krunk++)+"(clk, rst, "+
- describe(prefix)+"_r, "+
- describe(prefix)+"_a, "+
- describe(prefix)+", "+
- FabricTree.this.describe(prefix, left)+"_r, "+
- FabricTree.this.describe(prefix, left)+"_a, "+
- FabricTree.this.describe(prefix, left)+", "+
- FabricTree.this.describe(prefix, right)+"_r, "+
- FabricTree.this.describe(prefix, right)+"_a, "+
- FabricTree.this.describe(prefix, right)+
- ");");
- }
- dumpChannels(left, indentamount+1, decl);
- dumpChannels(right, indentamount+1, decl);
- }
- public void dumpChannels(Object o, int indentamount, boolean decl) {
- if (o==null) return;
- if (o instanceof Node) {
- ((Node)o).dumpChannels(indentamount, decl);
- } else {
- String indent = "";
- for(int i=0; i<indentamount; i++) indent += " ";
- if (decl) {
- String n = FabricTree.this.describe(prefix,o).startsWith("instruction")
- ? "[(`PACKET_WIDTH-1):0]" : "[(`PACKET_WIDTH-1):0]";
- System.out.println(" wire "+n+" "+indent+FabricTree.this.describe(prefix,o)+";");
- }
- }
- }
- public String describe(String prefix) {
- return prefix+name;
+ top_horn = mkNode((FabricElement[])dests.toArray(new FabricElement[0]), true);
+ FabricElement source = mkNode((FabricElement[])sources.toArray(new FabricElement[0]), false);
+ FunnelModule.FunnelInstance top_funnel = new FunnelModule.FunnelInstance(top, debug_in, source.getOutputPort());
+ ((FunnelModule.FunnelInstance)source).out = top_funnel;
+ //top_horn.addInput(top_funnel, top_funnel.getOutputPort());
+ top_funnel.addOutput(top_horn, top_horn.getInputPort());
+ }
+
+ public FabricElement mkNode(FabricElement[] ports, boolean is_horn) { return mkNode(ports, is_horn, 0, ports.length); }
+ public FabricElement mkNode(FabricElement[] ports, boolean is_horn, int start, int end) {
+ switch(end-start) {
+ case 0: return null;
+ case 1: return ports[start];
+ default: {
+ FabricElement leftPort = mkNode(ports, is_horn, start, (end+start)/2);
+ FabricElement rightPort = mkNode(ports, is_horn, (end+start)/2, end);
+ return is_horn
+ ? new HornModule.HornInstance(top, leftPort, rightPort)
+ : new FunnelModule.FunnelInstance(top, leftPort, rightPort);
}
}
}
- public static int krunk=0;
- private static String getUniqueName(Ship ship) {
- return ship.getType() + ship.getOrdinal();
- }
+ public Module getVerilogModule() { return top; }
- private static int count(Iterable<Destination> it) {
- int ret = 0;
- for(Destination d : it)
- ret++;
- return ret;
- }
+
+ // Expand //////////////////////////////////////////////////////////////////////////////
public void expand(ShipDescription sd) {
try {
FileOutputStream out = new FileOutputStream(outf);
PrintWriter pw = new PrintWriter(out);
- boolean auto =
- !"debug".equals(filename) &&
- !"execute".equals(filename) &&
- !"memory".equals(filename) &&
- !"fifo".equals(filename);
+ boolean auto = !"debug".equals(filename);
if (auto) {
pw.println("`include \"macros.v\"");
pw.println();
- pw.print("`define reset ");
- for(PumpDescription bb : sd) {
- String bb_name = bb.getName();
- if (bb.isInbox()) {
- pw.print(bb_name+"_a <= 1; ");
- } else {
- pw.print(bb_name+"_r <= 0; ");
+ pw.print("`define reset ");
+ for(DockDescription bb : sd) {
+ String bb_name = bb.getName();
+ if (bb.isInputDock()) pw.print(bb_name+"_a <= 1; ");
+ else pw.print(bb_name+"_r <= 0; ");
}
- }
- pw.println();
+ pw.println();
pw.println("module " + filename + "( clk, rst ");
- for(PumpDescription bb : sd) {
+ for(DockDescription bb : sd) {
String bb_name = bb.getName();
pw.print(" ");
- if (bb.isInbox()) {
+ if (bb.isInputDock()) {
pw.print(", " + bb_name+"_r");
pw.print(", " + bb_name+"_a_");
pw.print(", " + bb_name+"_d");
pw.println();
pw.println(" input clk;");
pw.println(" input rst;");
- for(PumpDescription bb : sd) {
+ for(DockDescription bb : sd) {
String bb_name = bb.getName();
pw.print(" ");
- if (bb.isInbox()) {
+ if (bb.isInputDock()) {
pw.println("`input(" +
bb_name+"_r, "+
bb_name+"_a, "+
bb_name+"_a_, "+
- "[(`PACKET_WIDTH-1):0],"+
+ "[("+WIDTH_WORD+"-1):0],"+
bb_name+"_d)"
);
} else {
bb_name+"_r, "+
bb_name+"_r_, "+
bb_name+"_a, "+
- "[(`PACKET_WIDTH-1):0],"+
+ "[("+WIDTH_WORD+"-1):0],"+
bb_name+"_d_)"
);
- pw.println("`defreg(" +
- bb_name+"_d_, "+
- "[(`PACKET_WIDTH-1):0],"+
- bb_name+"_d)"
- );
+ if (!bb_name.equals("out") || !"memory".equals(filename))
+ pw.println("`defreg(" +
+ bb_name+"_d_, "+
+ "[("+WIDTH_WORD+"-1):0],"+
+ bb_name+"_d)"
+ );
}
pw.println();
}
} catch (Exception e) { throw new RuntimeException(e); }
}
- public int computeOffset(int origin, int target) { return (target - origin)/6; }
- public int computeTarget(int origin, int offset) { return origin + (offset*6); }
-
private FpgaInstructionEncoder iie = new FpgaInstructionEncoder();
- public Instruction readInstruction(DataInputStream is) throws IOException { return iie.readInstruction(is); }
- public Instruction readInstruction(long instr) { return iie.readInstruction(instr); }
- public long writeInstruction(Instruction d) { return writeInstruction(d); }
- public void writeInstruction(DataOutputStream os, Instruction d) throws IOException { iie.writeInstruction(os, d); }
+ public Instruction readInstruction(DataInputStream is, Dock dispatchFrom) throws IOException { return iie.readInstruction(dispatchFrom, is); }
+ public Instruction readInstruction(Dock dispatchFrom, long instr) { return iie.readInstruction(dispatchFrom, instr); }
+ public long writeInstruction(Dock dispatchFrom, Instruction d) { return iie.writeInstruction(dispatchFrom, d); }
+ public void writeInstruction(DataOutputStream os, Dock dispatchFrom, Instruction d) throws IOException { iie.writeInstruction(os, dispatchFrom, d); }
+
+ private Ship debugShip;
+
+ public Dock getUniversalSource() { return debugShip.getDock("in"); }
private class FpgaInstructionEncoder extends InstructionEncoder {
- public long getDestAddr(Destination box) { return ((FpgaPump.VirtualPort)box).addr; }
- public long getBoxInstAddr(Pump box) { return ((FpgaPump)box).instr_addr; }
- public Destination getDestByAddr(long dest) {
+ public Dock getUniversalSource() { return debugShip.getDock("in"); }
+ public long getDestAddr(Path path) {
+ return ((FpgaPath)path).toLong();
+ }
+ public Path getPathByAddr(Dock source, long dest) {
for(Ship ship : Fpga.this)
- for(Pump bb : ship.getPumps())
- for(Destination d : bb.getDestinations())
- if (getDestAddr(d)==dest)
- return d;
+ for(Dock bb : ship) {
+ for(Destination d : new Destination[] { bb.getInstructionDestination(), bb.getDataDestination() }) {
+ for(BitVector signal : new BitVector[] { SIGNAL_ZERO, SIGNAL_ONE }) {
+ FpgaPath p = (FpgaPath)source.getPath(d, signal);
+ if (p.toLong() == dest) return p;
+ }
+ }
+ }
return null;
}
- public Pump getBoxByInstAddr(long dest) {
+ public Dock getBoxByInstAddr(long dest) {
for(Ship ship : Fpga.this)
- for(Pump bb : ship.getPumps())
- if (((FpgaPump)bb).instr_addr == dest)
+ for(Dock bb : ship)
+ if (((FpgaDestination)((FpgaDock)bb).getInstructionDestination()).getAddr() == dest)
return bb;
return null;
}
}
-
-}
\ No newline at end of file
+}
--- /dev/null
+package edu.berkeley.fleet.fpga;
+import edu.berkeley.fleet.api.*;
+import edu.berkeley.fleet.ies44.*;
+import edu.berkeley.fleet.*;
+import java.lang.reflect.*;
+import edu.berkeley.sbp.chr.*;
+import edu.berkeley.sbp.misc.*;
+import edu.berkeley.sbp.meta.*;
+import edu.berkeley.sbp.util.*;
+import java.util.*;
+import java.io.*;
+import static edu.berkeley.fleet.ies44.InstructionEncoder.*;
+import static edu.berkeley.fleet.verilog.Verilog.*;
+import edu.berkeley.fleet.api.*;
+import static edu.berkeley.fleet.verilog.Verilog.*;
+import edu.berkeley.fleet.api.Dock;
+import java.util.*;
+
+
+public class FpgaDestination extends Destination implements FabricElement {
+ private Module.Port port;
+ private FpgaDock dock;
+
+ public FpgaDestination(FpgaDock dock, Module.Port port, boolean isInstructionDestination) {
+ super(dock);
+ this.port = port;
+ this.dock = dock;
+ }
+
+ public Module.Port getOutputPort() { throw new RuntimeException(); }
+ public Module.Port getInputPort() { throw new RuntimeException(); }
+ public void addOutput(FabricElement out, Module.Port outPort) { throw new RuntimeException(); }
+
+ public long getAddr() {
+ return ((Fpga)dock.getShip().getFleet()).top_horn.getPath(this,null).toLong();
+ }
+ public FpgaPath getPath(FabricElement dest, BitVector signal) {
+ if (dest==this) return FpgaPath.emptyPath(this, signal);
+ return null;
+ }
+ public void addInput(FabricElement in, Module.Port inPort) {
+ inPort.connect((Module.SinkPort)port);
+ }
+ public String toString() {
+ return dock.toString();
+ }
+}
--- /dev/null
+package edu.berkeley.fleet.fpga;
+import edu.berkeley.fleet.api.*;
+import edu.berkeley.fleet.ies44.*;
+import edu.berkeley.fleet.*;
+import java.lang.reflect.*;
+import edu.berkeley.sbp.chr.*;
+import edu.berkeley.sbp.misc.*;
+import edu.berkeley.sbp.meta.*;
+import edu.berkeley.sbp.util.*;
+import java.util.*;
+import java.io.*;
+import static edu.berkeley.fleet.ies44.InstructionEncoder.*;
+import static edu.berkeley.fleet.verilog.Verilog.*;
+import edu.berkeley.fleet.api.*;
+import static edu.berkeley.fleet.verilog.Verilog.*;
+import edu.berkeley.fleet.api.Dock;
+import edu.berkeley.fleet.two.*;
+import java.util.*;
+
+
+/** the pump itself is a */
+public class FpgaDock extends FleetTwoDock implements FabricElement {
+
+ private static final int INSTRUCTION_FIFO_SIZE = 8;
+
+ private FpgaDestination dataDestination;
+ private FpgaDestination instructionDestination;
+
+ private Module.InstantiatedModule instance;
+
+ public Module.InstantiatedModule getInstance() { return instance; }
+
+ public Destination getDataDestination() { return dataDestination; }
+ public Destination getInstructionDestination() { return instructionDestination; }
+ public int getInstructionFifoSize() { return INSTRUCTION_FIFO_SIZE; }
+
+ FpgaDock(FpgaShip ship, DockDescription bbd) {
+ super(ship, bbd);
+ this.instance = new Module.InstantiatedModule(((Fpga)ship.getFleet()).top, new DockModule(isInputDock()));
+ this.dataDestination = new FpgaDestination(this, this.instance.getInputPort("fabric_in"), false);
+ this.instructionDestination = new FpgaDestination(this, this.instance.getInputPort("instruction"), true);
+ Module.InstantiatedModule shipm = ship.getVerilogModule();
+ if (isInputDock()) {
+ instance.getOutputPort("ship").connect(shipm.getInputPort(getName()));
+ } else {
+ shipm.getOutputPort(getName()).connect(instance.getInputPort("ship"));
+ }
+ }
+
+
+ // FabricElement methods //////////////////////////////////////////////////////////////////////////////
+
+ private FabricElement upstream;
+ public Module.Port getOutputPort() { throw new RuntimeException(); }
+ public Module.Port getInputPort() { throw new RuntimeException(); }
+ public FpgaPath getPath(FabricElement dest, BitVector signal) { return upstream.getPath((FabricElement)dest, signal); }
+ public FpgaPath getPath(Destination dest,BitVector signal) { return upstream.getPath((FabricElement)dest, signal); }
+ public void addInput(FabricElement in, Module.Port inPort) { throw new RuntimeException(); }
+ public void addOutput(FabricElement out, Module.Port outPort) {
+ this.upstream = out;
+ instance.getOutputPort("fabric_out").connect((Module.SinkPort)outPort);
+ }
+
+ public static class DockModule extends Module {
+
+ public DockModule(boolean inbox) {
+ super(inbox ? "inbox" : "outbox");
+ Module fifo4 = new FifoModule(4);
+ Module fifo8 = new FifoModule(8);
+ Module fifo = fifo8;
+ Module ififo_m = new FifoModule(INSTRUCTION_FIFO_SIZE);
+ Module efifo_m = fifo4;
+ Module.SourcePort instruction = createInputPort("instruction", WIDTH_PACKET);
+ instruction.hasLatch = true;
+
+ Module.SourcePort fabric_in = createInputPort("fabric_in", WIDTH_PACKET);
+ Module.SinkPort fabric_out = createOutputPort("fabric_out", WIDTH_PACKET, "");
+ Module.InstantiatedModule dfifo = new Module.InstantiatedModule(this, fifo);
+ fabric_in.connect(dfifo.getInputPort("in"));
+
+ Module.SourcePort dfifo_out = dfifo.getOutputPort("out");
+ Module.SourcePort ship_out = null;
+ if (!inbox) {
+ ship_out = createInputPort("ship", WIDTH_WORD);
+ ship_out.hasLatch = true;
+ }
+
+ Module.SinkPort ship_in = null;
+ if (inbox) {
+ ship_in = createOutputPort("ship", WIDTH_PACKET, "");
+ ship_in.hasLatch = true;
+ }
+
+ Module.Latch ondeck = new Latch("ondeck", WIDTH_WORD);
+ Module.Latch repeat_counter = new Latch("repeat_counter", SET_ILC_FROM_IMMEDIATE.valmaskwidth+1, 1);
+ Module.Latch loop_counter = new Latch("loop_counter", SET_OLC_FROM_IMMEDIATE.valmaskwidth, 1);
+ Module.Latch tapl = new Latch("tapl", SET_TAPL_FROM_IMMEDIATE.valmaskwidth);
+ Module.Latch flag_a = new Latch("flag_a", 1);
+ Module.Latch flag_b = new Latch("flag_b", 1);
+ Module.Latch flag_c = new Latch("flag_c", 1);
+ Module.StateWire ondeckFull = new StateWire("ondeck_full");
+ Module.StateWire newMayProceed = new StateWire("newmayproceed", true);
+ Module.StateWire doRepeat = new StateWire("dorepeat", false);
+
+ Module.StateWire isHatchOpen = new StateWire("hatch", true);
+
+ Module.SinkPort token_out = fabric_out;
+ Module.SourcePort token_in = dfifo_out;
+ Module.SinkPort data_out = inbox ? ship_in : fabric_out;
+ Module.SourcePort data_in = inbox ? dfifo_out : ship_out;
+
+ Module.InstantiatedModule ififo = new Module.InstantiatedModule(this, ififo_m);
+ Module.SinkPort ififo_in = ififo.getInputPort("in");
+ Module.SourcePort ififo_out = ififo.getOutputPort("out");
+
+ Module.InstantiatedModule efifo = new Module.InstantiatedModule(this, efifo_m);
+ Module.SinkPort efifo_in = efifo.getInputPort("in");
+ Module.SourcePort efifo_out = efifo.getOutputPort("out");
+ efifo_in.hasLatch = true;
+
+ addPreCrap("wire [(`DATAWIDTH-1):0] data_latch_output;");
+ addPreCrap("wire [(`DATAWIDTH-1):0] data_latch_input;");
+ addPreCrap("assign data_latch_output = " +
+ (inbox ? data_out.getName() : "`packet_data("+data_out.getName()+")")+";");
+ addPreCrap("assign data_latch_input = " +
+ (inbox ? "`packet_data("+data_in.getName()+")" : data_in.getName())+";");
+ Assignable data_latch = new SimpleAssignable(inbox ? data_out.getName() :
+ "`packet_data("+data_out.getName()+")");
+ String data_latch_input = "data_latch_input";
+
+ // Open the Hatch
+ new Event(new Object[] { "loop_counter==0" },
+ new Action[] { isHatchOpen.doFill() });
+
+ // Torpedo Arrival
+ new Event(new Object[] { instruction,
+ PACKET_TOKEN.verilogVal("instruction"),
+ ondeckFull.isFull(),
+ token_out,
+ I.verilog("ondeck"),
+ },
+ new Action[] { instruction,
+ ondeckFull.doDrain(),
+ newMayProceed.doFill(),
+ new AssignAction(loop_counter, "0"),
+ new AssignAction(repeat_counter, "1"),
+ new AssignAction(new SimpleAssignable("`packet_token("+token_out.getName()+")"), "1"),
+ new AssignAction(new SimpleAssignable("`packet_dest("+token_out.getName()+")"), "tapl"),
+ token_out,
+ isHatchOpen.doFill(),
+ });
+ // Non-Torpedo Arrival
+ new Event(new Object[] { instruction,
+ efifo_in,
+ "!("+PACKET_TOKEN.verilogVal("instruction")+")"
+ },
+ new Action[] {
+ efifo_in,
+ instruction,
+ new AssignAction(efifo_in, instruction)
+ });
+
+ // Tail
+ new Event(new Object[] { efifo_out, TAIL.verilog("`packet_data("+efifo_out.getName()+")") },
+ new Action[] { efifo_out, isHatchOpen.doDrain() } );
+ // Enqueue
+ new Event(new Object[] { efifo_out,
+ ififo_in,
+ "!("+TAIL.verilog("`packet_data("+efifo_out.getName()+")")+")",
+ isHatchOpen.isFull() },
+ new Action[] { efifo_out, ififo_in, new AssignAction(ififo_in, "`packet_data("+efifo_out.getName()+")") } );
+
+ // New
+ new Event(new Object[] { ififo_out,
+ ondeckFull.isEmpty(),
+ newMayProceed.isFull(),
+ },
+ new Action[] { ififo_out,
+ ondeckFull.doFill(),
+ newMayProceed.doDrain(),
+ new AssignAction(ondeck, ififo_out)
+ }
+ );
+
+ // RepeatExecute
+ new Event(new Object[] { doRepeat.isFull() },
+ new Action[] { doRepeat.doDrain(), ondeckFull.doFill(),
+ new AssignAction(repeat_counter,
+ "repeat_counter==`magic_standing_value?`magic_standing_value:(repeat_counter-1)")
+ });
+
+ // Execute
+ new Event(
+ new Object[] { ondeckFull.isFull(),
+ data_out,
+ token_out,
+ ififo_in,
+ "(!`predicate_met(ondeck) || "+OS.verilog("ondeck")+" || !hatch)",
+ new ConditionalTrigger("(`predicate_met(ondeck) && `instruction_bit_datain(ondeck))", data_in),
+ new ConditionalTrigger("(`predicate_met(ondeck) && `instruction_bit_tokenin(ondeck))", token_in)
+ },
+ new Action[] { ondeckFull.doDrain(),
+ new ConditionalAction("`done_executing(ondeck)", newMayProceed.doFill()),
+ new ConditionalAction("`done_executing(ondeck) && `instruction_is_normal(ondeck)",
+ new AssignAction(repeat_counter, "1")),
+ new ConditionalAction("`should_requeue(ondeck) && `done_executing(ondeck)", ififo_in),
+ new ConditionalAction("`should_requeue(ondeck) && `done_executing(ondeck)", new AssignAction(ififo_in, ondeck)),
+ new ConditionalAction("!`done_executing(ondeck)", doRepeat.doFill()),
+
+ new ConditionalAction("`predicate_met(ondeck) && `instruction_is_load_data_to_loop(ondeck)",
+ new AssignAction(loop_counter, "data_latch_output")),
+ new ConditionalAction("`predicate_met(ondeck) && `instruction_is_load_immediate_to_loop(ondeck)",
+ new AssignAction(loop_counter, "`instruction_loop_count_immediate(ondeck)")),
+ new ConditionalAction("`predicate_met(ondeck) && `instruction_is_decr_loop(ondeck)",
+ new AssignAction(loop_counter, "loop_counter==0 ? 0 : (loop_counter-1)")),
+
+ new ConditionalAction("`predicate_met(ondeck) && `instruction_is_load_data_to_repeat(ondeck)",
+ new AssignAction(repeat_counter, "data_latch_output")),
+ new ConditionalAction("`predicate_met(ondeck) && `instruction_is_load_immediate_to_repeat(ondeck)",
+ new AssignAction(repeat_counter, "`instruction_repeat_count_immediate(ondeck)")),
+ new ConditionalAction("`predicate_met(ondeck) && `instruction_is_load_standing_to_repeat(ondeck)",
+ new AssignAction(repeat_counter, "`magic_standing_value")),
+ new ConditionalAction("`predicate_met(ondeck) &&"+SHIFT.verilog("ondeck"),
+ new AssignAction(data_latch,
+ "({ data_latch_output["+(WIDTH_WORD-1-19)+":0], 19'b0 } | "+
+ SHIFT.verilogVal("ondeck")+")")),
+ new ConditionalAction("`predicate_met(ondeck) && "+SET_IMMEDIATE.verilog("ondeck"),
+ new AssignAction(data_latch,
+ "{ {"+(WIDTH_WORD-InstructionEncoder.DataLatch_WIDTH)+
+ "{"+SET_IMMEDIATE_EXTEND.verilogVal("ondeck")+"}}, "+
+ SET_IMMEDIATE.verilogVal("ondeck")+" }")),
+ new ConditionalAction("`predicate_met(ondeck) && `instruction_is_setflags(ondeck)",
+ new AssignAction(flag_a, "`new_flag_a(ondeck)")),
+ new ConditionalAction("`predicate_met(ondeck) && `instruction_is_setflags(ondeck)",
+ new AssignAction(flag_b, "`new_flag_b(ondeck)")),
+ (inbox
+ ? new ConditionalAction("`predicate_met(ondeck) && "+
+ "(`instruction_bit_datain(ondeck) || `instruction_bit_tokenin(ondeck))",
+ new AssignAction(flag_c, PACKET_SIGNAL.verilogVal(dfifo_out.getName())))
+ : new ConditionalAction("`predicate_met(ondeck) && "+
+ "(!`instruction_bit_datain(ondeck) && `instruction_bit_tokenin(ondeck))",
+ new AssignAction(flag_c, PACKET_SIGNAL.verilogVal(dfifo_out.getName())))
+ /* FIXME: C-flag-from-ship */
+ ),
+ new ConditionalAction("`predicate_met(ondeck) && `instruction_bit_datain(ondeck)", data_in),
+ new ConditionalAction("`predicate_met(ondeck) && `instruction_bit_dataout(ondeck)", data_out),
+ new ConditionalAction("`predicate_met(ondeck) && `instruction_bit_tokenin(ondeck)", token_in),
+ new ConditionalAction("`predicate_met(ondeck) && `instruction_bit_tokenout(ondeck)", token_out),
+ new ConditionalAction("`predicate_met(ondeck) && `instruction_bit_tokenout(ondeck)",
+ new AssignAction(new SimpleAssignable("`packet_token("+token_out.getName()+")"),
+ "1")),
+ new ConditionalAction("`predicate_met(ondeck) && !`instruction_bit_tokenout(ondeck)",
+ new AssignAction(new SimpleAssignable("`packet_token("+token_out.getName()+")"),
+ "0")),
+ new ConditionalAction("`predicate_met(ondeck) && `instruction_bit_latch(ondeck)",
+ new AssignAction(data_latch, data_latch_input)),
+ new ConditionalAction("`predicate_met(ondeck) && `instruction_path_from_data(ondeck)",
+ new AssignAction(new SimpleAssignable("`packet_signal_and_dest("+token_out.getName()+")"),
+ DISPATCH_PATH.verilogVal(data_latch_input))),
+ new ConditionalAction("`predicate_met(ondeck) && "+SET_TAPL_FROM_IMMEDIATE.verilog("ondeck"),
+ new AssignAction(tapl, SET_TAPL_FROM_IMMEDIATE.verilogVal("ondeck"))),
+ new ConditionalAction("`predicate_met(ondeck) && `instruction_path_from_immediate(ondeck)",
+ new AssignAction(new SimpleAssignable("`packet_signal_and_dest("+token_out.getName()+")"),
+ "`instruction_path_immediate(ondeck)")),
+ }
+ );
+ }
+
+ public void dump(PrintWriter pw, boolean fix) {
+
+ pw.println("`define packet_signal_and_dest(p) { "+PACKET_SIGNAL.verilogVal("p")+", "+PACKET_DEST.verilogVal("p")+" }");
+ pw.println("`define instruction_is_load_data_to_repeat(i) "+SET_ILC_FROM_DATA_LATCH.verilog("i"));
+ pw.println("`define instruction_is_load_data_to_loop(i) "+SET_OLC_FROM_DATA_LATCH.verilog("i"));
+ pw.println("`define instruction_is_load_immediate_to_repeat(i) "+SET_ILC_FROM_IMMEDIATE.verilog("i"));
+ pw.println("`define instruction_is_load_immediate_to_loop(i) "+SET_OLC_FROM_IMMEDIATE.verilog("i"));
+ pw.println("`define instruction_is_load_standing_to_repeat(i) "+SET_ILC_FROM_INFINITY.verilog("i"));
+ pw.println("`define instruction_repeat_count_immediate(i) "+SET_ILC_FROM_IMMEDIATE.verilogVal("i"));
+ pw.println("`define instruction_loop_count_immediate(i) "+SET_OLC_FROM_IMMEDIATE.verilogVal("i"));
+
+ pw.println("`define instruction_path_immediate(i) "+PATH_IMMEDIATE.verilogVal("i"));
+ pw.println("`define instruction_path_from_immediate(i) "+PATH_IMMEDIATE.verilog("i"));
+ pw.println("`define instruction_path_from_data(i) "+PATH_DATA.verilog("i"));
+
+ pw.println("`define instruction_is_tail(i) "+TAIL.verilog("i"));
+ pw.println("`define instruction_is_normal(i) "+MOVE.verilog("i"));
+ pw.println("`define instruction_is_setflags(i) "+SET_FLAGS.verilog("i"));
+ pw.println("`define instruction_is_set(i) "+SET.verilog("i"));
+
+ pw.println("`define instruction_is_decr_loop(i) "+SET_OLC_FROM_OLC_MINUS_ONE.verilog("i"));
+
+ pw.println("`define instruction_bit_tokenout(i) (`instruction_is_normal(i) && "+TO.verilog("i")+")");
+ pw.println("`define instruction_bit_dataout(i) (`instruction_is_normal(i) && "+DO.verilog("i")+")");
+ pw.println("`define instruction_bit_latch(i) (`instruction_is_normal(i) && "+DC.verilog("i")+")");
+ pw.println("`define instruction_bit_datain(i) (`instruction_is_normal(i) && "+DI.verilog("i")+")");
+ pw.println("`define instruction_bit_tokenin(i) (`instruction_is_normal(i) && "+TI.verilog("i")+")");
+ pw.println("`define should_requeue(i) (loop_counter > 0 && !("+OS.verilog("i")+"))");
+ pw.println("`define predicate_met(i) ("+
+ "("+
+ "!`instruction_is_normal(i) || repeat_counter>0"+
+ ") && ("+
+ " " + P_A.verilog("i")+" ? flag_a "+
+ ":" + P_B.verilog("i")+" ? flag_b "+
+ ":" + P_C.verilog("i")+" ? flag_c "+
+ ":" + P_NOT_A.verilog("i")+" ? !flag_a "+
+ ":" + P_NOT_B.verilog("i")+" ? !flag_b "+
+ ":" + P_NOT_C.verilog("i")+" ? !flag_c "+
+ ":" + P_OLC.verilog("i")+" ? (loop_counter>0) "+
+ ": 1"+
+ ")"+
+ ")");
+ pw.println("`define new_flag(x) ("+
+ "( ((x >> 0) & 1) & !flag_c) |" +
+ "( ((x >> 1) & 1) & flag_c) |" +
+ "( ((x >> 2) & 1) & !flag_b) |" +
+ "( ((x >> 3) & 1) & flag_b) |" +
+ "( ((x >> 4) & 1) & !flag_a) |" +
+ "( ((x >> 5) & 1) & flag_a) | 0" +
+ ")");
+ pw.println("`define new_flag_a(i) `new_flag("+SET_FLAGS_A.verilogVal("i")+")");
+ pw.println("`define new_flag_b(i) `new_flag("+SET_FLAGS_B.verilogVal("i")+")");
+ pw.println("`define done_executing(i) (repeat_counter==0 || repeat_counter==1 || !`instruction_is_normal(i))");
+
+ pw.println("`define magic_standing_value (1<<"+SET_ILC_FROM_IMMEDIATE.valmaskwidth+")");
+
+ super.dump(pw,fix);
+ }
+ }
+}
--- /dev/null
+package edu.berkeley.fleet.fpga;
+import edu.berkeley.fleet.api.*;
+import edu.berkeley.fleet.ies44.*;
+import edu.berkeley.fleet.*;
+import java.lang.reflect.*;
+import edu.berkeley.sbp.chr.*;
+import edu.berkeley.sbp.misc.*;
+import edu.berkeley.sbp.meta.*;
+import edu.berkeley.sbp.util.*;
+import java.util.*;
+import java.io.*;
+import static edu.berkeley.fleet.ies44.InstructionEncoder.*;
+import static edu.berkeley.fleet.verilog.Verilog.*;
+
+
+public class FpgaPath extends Path {
+
+ private boolean[] path;
+ private FpgaDestination dest;
+ public final BitVector signal;
+
+ public Dock getSource() { throw new RuntimeException("not implemented"); }
+ public Destination getDestination() { return dest; }
+
+ private FpgaPath(boolean[] path, FpgaDestination dest, BitVector signal) {
+ this.signal = signal;
+ this.path = path;
+ this.dest = dest;
+ }
+
+ public long toLong() {
+ long ret = 0;
+ for(int i=0; i<path.length; i++) {
+ if (path[i]) ret |= (1 << i);
+ }
+ if (signal != null)
+ for(int i=0; i<signal.length(); i++) {
+ if (signal.get(i))
+ ret |= (1L << (i+11));
+ }
+ return ret;
+ }
+
+ public String toString() {
+ StringBuffer ret = new StringBuffer();
+ for(int i=0; i<path.length; i++) {
+ if (i>0) ret.append('_');
+ ret.append(path[i] ? "1" : "0");
+ }
+ return ret.toString()+(signal==null?"":(":"+signal));
+ }
+
+ public FpgaPath prepend(boolean b) {
+ boolean[] newpath = new boolean[path.length+1];
+ System.arraycopy(path, 0, newpath, 1, path.length);
+ newpath[0] = b;
+ return new FpgaPath(newpath, dest, signal);
+ }
+ public FpgaPath append(boolean b, FpgaDestination newdest) {
+ boolean[] newpath = new boolean[path.length+1];
+ System.arraycopy(path, 0, newpath, 0, path.length);
+ newpath[newpath.length-1] = b;
+ return new FpgaPath(newpath, newdest, signal);
+ }
+
+ public int getBufferingAmount() {
+ throw new RuntimeException("not implemented");
+ }
+
+ public int getLatencyMetric() {
+ return 0;
+ }
+
+ public static FpgaPath emptyPath(FpgaDestination dest, BitVector signal) {
+ return new FpgaPath(new boolean[0], dest, signal);
+ }
+
+ public BitVector getSignal() { return null; }
+
+}
+++ /dev/null
-package edu.berkeley.fleet.fpga;
-import edu.berkeley.fleet.doc.*;
-import edu.berkeley.fleet.api.*;
-import edu.berkeley.fleet.api.*;
-import edu.berkeley.fleet.api.Pump;
-import java.util.*;
-
-/** anything that has a destination address on the switch fabric */
-public class FpgaPump extends Pump {
-
- private final String name;
- private final FpgaShip ship;
- private Destination[] ports;
-
- public Iterable<Destination> getDestinations() {
- ArrayList<Destination> ret = new ArrayList<Destination>();
- for(Destination d : ports) ret.add(d);
- return ret;
- }
- private static int default_addr;
- private static int default_instr_addr;
-
- public int bits;
- public int addr = (default_addr++);
- public int instr_bits;
- public int instr_addr = (default_instr_addr++);
- private final PumpDescription bbd;
- protected boolean special = false;
- protected boolean ihorn = false;
- protected boolean dhorn = false;
- void service() { }
- public boolean special() { return special; }
- public boolean ihorn() { return ihorn; }
- public boolean dhorn() { return dhorn; }
- public boolean inbox;
- public boolean isInbox() { return inbox; }
- public boolean isOutbox() { return !inbox; }
- public long resolveLiteral(String literal) {
- return bbd.resolveLiteral(literal);
- }
- public FpgaPump(PumpDescription bbd, boolean inbox, FpgaShip ship, String name) {
- this(bbd, inbox, ship, name, false, false, false);
- }
- public FpgaPump(PumpDescription bbd, boolean inbox, FpgaShip ship, String name, boolean special) {
- this(bbd, inbox, ship, name, special, false, false);
- }
- public FpgaPump(PumpDescription bbd, boolean inbox, FpgaShip ship, String name, boolean special, boolean ihorn, boolean dhorn) {
- this.bbd = bbd;
- this.inbox = inbox;
- this.special = special;
- this.dhorn = dhorn;
- this.ihorn = ihorn;
- this.ship = ship;
- this.name = name;
- String[] ports = new String[] { "" };
- this.ports = new Destination[ports.length];
- for(int i=0; i<ports.length; i++)
- this.ports[i] = new VirtualPort(ports[i]);
- ship.addPump(name, this);
- }
-
- public void addDestination(String dest) {
- Destination[] newports = new Destination[ports.length+1];
- System.arraycopy(ports, 0, newports, 0, ports.length);
- newports[newports.length-1] = new VirtualPort(dest);
- ports = newports;
- }
-
- public class VirtualPort extends Destination {
- public String name;
- public VirtualPort(String name) { this.name = name; }
- public String getDestinationName() { return name; }
- public Ship getShip() { return FpgaPump.this.getShip(); }
- public void addDataFromFabric(long data) { FpgaPump.this.addDataFromFabric(name, (int)data); }
- public String toString() { return getShip()+"."+getName(); }
- // fixme
- public long addr = (default_addr++);
- }
-
- /** adds one token to the port from the switch fabric side */
- void addTokenFromFabric() { addDataFromFabric(0); }
-
- /** adds the included datum to the port from the switch fabric side */
- void addDataFromFabric(int datum) { throw new RuntimeException("this should never happen!"); }
- void addDataFromFabric(String name, int datum) {
- addDataFromFabric(datum);
- }
-
- /** adds one token to the port from the ship side */
- public void addTokenFromShip() { addDataFromShip(0); }
-
- /** adds the included datum to the port from the switch fabric side */
- public void addDataFromShip(int datum) { throw new RuntimeException("this should never happen!"); }
-
- public Ship getShip() { return ship; }
-
- public Fleet getFleet() { return getShip().getFleet(); }
-
- public String toString() { return ship+"."+name; }
-
- public String getName() { return name; }
-
- public int getInstructionFifoLength() { return 4; }
-
-}
package edu.berkeley.fleet.fpga;
-import edu.berkeley.fleet.doc.*;
import edu.berkeley.fleet.api.*;
import java.util.*;
import java.io.*;
+import edu.berkeley.fleet.two.*;
+import static edu.berkeley.fleet.ies44.InstructionEncoder.*;
+import static edu.berkeley.fleet.verilog.Verilog.*;
/** a ship, which belongs to a fleet and which may have many ports */
-public class FpgaShip extends Ship {
+public class FpgaShip extends FleetTwoShip {
+ private Module module;
+ private Module.InstantiatedModule instance;
+ private LinkedHashMap<String,FpgaDock> ports = new LinkedHashMap<String,FpgaDock>();
+
/** You should instantiate a bunch of Inboxes and Outboxes in your constructor */
- public FpgaShip(Fpga fleet, String name, String type, ShipDescription sd) {
- this.fleet = fleet; this.type = type;
- for(PumpDescription sdbb : sd) {
- FpgaPump sbb = new FpgaPump(sdbb, sdbb.isInbox(), this, sdbb.getName());
- for(String port : sdbb) {
- if (port.equals("")) continue;
- sbb.addDestination(port);
- }
- }
- if (type.equals("Debug")) {
- new FpgaPump(null, false, this, "out", true);
-
- } else if (type.equals("Execute")) {
- new FpgaPump(null, false, this, "ihorn", true, true, false);
- new FpgaPump(null, false, this, "dhorn", true, false, true);
-
- } else if (type.equals("Memory")) {
- new FpgaPump(null, true, this, "command", true);
- new FpgaPump(null, false, this, "ihorn", true, true, false);
- new FpgaPump(null, false, this, "dhorn", true, false, true);
+ public FpgaShip(Fpga fleet, ShipDescription sd) {
+ super(fleet, sd);
+ this.module = new Module(getType().toLowerCase());
+ this.instance = new Module.InstantiatedModule(fleet.getVerilogModule(), module);
+ for(DockDescription sdbb : sd) {
+ if (sdbb.isInputDock()) module.createInputPort(sdbb.getName(), WIDTH_WORD);
+ else module.createOutputPort(sdbb.getName(), WIDTH_WORD, "");
+ ports.put(sdbb.getName(), new FpgaDock(this, sdbb));
}
+ if (getType().toLowerCase().equals("debug"))
+ module.createOutputPort("debug_out", WIDTH_WORD, "");
}
- private Fpga fleet;
- private String type;
-
- public long resolveLiteral(String s) {
- if (s.equals("NEG")) return 0;
- if (s.equals("INC")) return 1;
- if (s.equals("DEC")) return 2;
- if (s.equals("ABS")) return 3;
- if (s.equals("ADD")) return 0;
- if (s.equals("SUB")) return 1;
- if (s.equals("MAX")) return 2;
- if (s.equals("MIN")) return 3;
- return super.resolveLiteral(s);
- }
-
- // this is dumb, the fpga fleet currently requires these in declaration-order; it shouldn't
- private ArrayList<FpgaPump> portlist = new ArrayList<FpgaPump>();
- private HashMap<String,FpgaPump> ports = new HashMap<String,FpgaPump>();
-
- public Iterable<Pump> getPumps() { return (Iterable<Pump>)(Object)portlist; }
- public String getType() { return type; }
- public Fleet getFleet() { return fleet; }
- public Fpga getSlipway() { return fleet; }
-
- void addPump(String name, FpgaPump port) { ports.put(name, port); portlist.add(port); }
+ public Iterator<Dock> iterator() { return (Iterator<Dock>)(Object)ports.values().iterator(); }
+ public Module.InstantiatedModule getVerilogModule() { return instance; }
}
--- /dev/null
+package edu.berkeley.fleet.fpga;
+import edu.berkeley.fleet.api.*;
+import edu.berkeley.fleet.ies44.*;
+import edu.berkeley.fleet.*;
+import java.lang.reflect.*;
+import edu.berkeley.sbp.chr.*;
+import edu.berkeley.sbp.misc.*;
+import edu.berkeley.sbp.meta.*;
+import edu.berkeley.sbp.util.*;
+import java.util.*;
+import java.io.*;
+import static edu.berkeley.fleet.ies44.InstructionEncoder.*;
+import static edu.berkeley.fleet.verilog.Verilog.*;
+
+
+public class FunnelModule extends Module {
+
+ public FunnelModule() {
+ super("funnel");
+ Module.SinkPort outp = createOutputPort("out", WIDTH_PACKET, "");
+ Module.SourcePort in1p = createInputPort("in1", WIDTH_PACKET);
+ Module.SourcePort in2p = createInputPort("in2", WIDTH_PACKET);
+ new Event(new Object[] { in1p, outp },
+ new Action[] { in1p, outp,
+ new AssignAction(outp, in1p) });
+ new Event(new Object[] { in2p, outp },
+ new Action[] { in2p, outp,
+ new AssignAction(outp, in2p) });
+ }
+
+ public static class FunnelInstance extends Module.InstantiatedModule implements FabricElement {
+ private FabricElement in1 = null;
+ private FabricElement in2 = null;
+ public FabricElement out = null;
+ public Module.Port getOutputPort() { return getOutputPort("out"); }
+ public Module.Port getInputPort() { throw new RuntimeException("funnel has multiple inputs"); }
+ public FunnelInstance(Module thisModule, Module.Port p1, Module.Port p2) {
+ super(thisModule, new FunnelModule());
+ p1.connect(this.getInputPort("in1"));
+ p2.connect(this.getInputPort("in2"));
+ }
+ public FunnelInstance(Module thisModule, FabricElement in1, FabricElement in2) {
+ super(thisModule, new FunnelModule());
+ this.in1 = in1;
+ this.in2 = in2;
+ in1.addOutput(this, this.getInputPort("in1"));
+ in2.addOutput(this, this.getInputPort("in2"));
+ }
+ public void addOutput(FabricElement out, Module.Port outPort) {
+ this.out = out;
+ getOutputPort("out").connect((Module.SinkPort)outPort);
+ }
+ public void addInput(FabricElement in, Module.Port source) {
+ throw new RuntimeException("cannot add inputs to a funnel once constructed");
+ }
+ public FpgaPath getPath(FabricElement dest, BitVector signal) {
+ return out.getPath(dest, signal);
+ }
+ }
+
+}
+++ /dev/null
-// note: got rid of funnel "fairness" code
-package edu.berkeley.fleet.fpga;
-import edu.berkeley.fleet.doc.*;
-import edu.berkeley.fleet.api.*;
-import edu.berkeley.fleet.ies44.*;
-import edu.berkeley.fleet.*;
-import java.lang.reflect.*;
-import edu.berkeley.sbp.chr.*;
-import edu.berkeley.sbp.misc.*;
-import edu.berkeley.sbp.meta.*;
-import edu.berkeley.sbp.util.*;
-import java.util.*;
-import java.io.*;
-import static edu.berkeley.fleet.ies44.InstructionEncoder.*;
-
-public class Generator {
-
- public static final int WIDTH_PACKET = WIDTH_WORD + WIDTH_ADDR;
-
- public static class SimpleValue implements Value {
- private final String s;
- public SimpleValue(String s) { this.s = s; }
- public SimpleValue(String s, int high, int low) { this.s = s+"["+high+":"+low+"]"; }
- public Value getBits(int high, int low) { return new SimpleValue(s, high, low); }
- public Assignable getAssignableBits(int high, int low) { return new SimpleValue(s, high, low); }
- public String getVerilogName() { return s; }
- public String toString() { return s; }
- }
-
- public static interface Action {
- public String getVerilogAction();
- }
-
- public static interface Trigger {
- public String getVerilogTrigger();
- }
-
- public static interface Assignable {
- public String getVerilogName();
- public Assignable getAssignableBits(int high, int low);
- }
-
- public static interface Value extends Assignable {
- public String getVerilogName();
- public Value getBits(int high, int low);
- }
-
- public static class ConditionalAction implements Action {
- private String condition;
- private Action action;
- public ConditionalAction(String condition, Action action) {
- this.condition = condition;
- this.action = action;
- }
- public String toString() { return getVerilogAction(); }
- public String getVerilogAction() { return "if ("+condition+") begin "+action.getVerilogAction()+" end"; }
- }
-
- public static class ConditionalTrigger implements Trigger {
- private String condition;
- private Trigger trigger;
- public ConditionalTrigger(String condition, Trigger trigger) {
- this.condition = condition;
- this.trigger = trigger;
- if (trigger instanceof Module.Port)
- ((Module.Port)trigger).hasLatch = true;
- }
- public String getVerilogTrigger() {
- return "&& (("+condition+") ? (1 " + trigger.getVerilogTrigger() + ") : 1)";
- }
- }
-
- public static class SimpleAssignable implements Assignable {
- private final String s;
- public SimpleAssignable(String s) { this.s = s; }
- public String getVerilogName() { return s; }
- public Assignable getAssignableBits(int high, int low) { return new SimpleValue(s, high, low); }
- }
-
- public static class AssignAction implements Action {
- private String left;
- private String right;
- public AssignAction(Assignable left, Value right) {
- this.left = left.getVerilogName();
- this.right = right.getVerilogName().toString();
- }
- public AssignAction(Assignable left, String right) {
- this.left = left.getVerilogName();
- this.right = right;
- }
- public String getVerilogAction() { return left + "<=" + right + ";"; }
- public String toString() { return getVerilogAction(); }
- }
-
- public static class SimpleAction implements Action {
- private final String verilog;
- public SimpleAction(String verilog) { this.verilog = verilog; }
- public String getVerilogAction() { return verilog; }
- public String toString() { return verilog; }
- }
-
- public static class Module {
- private int id = 0;
- private final String name;
- public String getName() { return name; }
- public Port getPort(String name) { return ports.get(name); }
-
- private HashSet<InstantiatedModule> instantiatedModules = new HashSet<InstantiatedModule>();
- private final ArrayList<Event> events = new ArrayList<Event>();
-
- // FIXME: always-alphabetical convention?
- private final HashMap<String,Port> ports = new HashMap<String,Port>();
- private final ArrayList<String> portorder = new ArrayList<String>();
- private final HashMap<String,StateWire> statewires = new HashMap<String,StateWire>();
- private final HashMap<String,Latch> latches = new HashMap<String,Latch>();
-
- private StringBuffer crap = new StringBuffer();
- private StringBuffer precrap = new StringBuffer();
- public void addCrap(String s) { crap.append(s); crap.append('\n'); }
- public void addPreCrap(String s) { precrap.append(s); precrap.append('\n'); }
-
- public Module(String name) {
- this.name = name;
- }
-
- public SourcePort createInputPort(String name, int width) {
- if (ports.get(name)!=null) throw new RuntimeException();
- return new SourcePort(name, width, true);
- }
- public SourcePort getInputPort(String name) {
- SourcePort ret = (SourcePort)ports.get(name);
- if (ret==null) throw new RuntimeException();
- return ret;
- }
- public SinkPort createOutputPort(String name, int width, String resetBehavior) {
- if (ports.get(name)!=null) throw new RuntimeException();
- return new SinkPort(name, width, true, resetBehavior);
- }
- public SinkPort getOutputPort(String name) {
- SinkPort ret = (SinkPort)ports.get(name);
- if (ret==null) throw new RuntimeException();
- return ret;
- }
-
- private class StateWire {
- public final String name;
- public final boolean initiallyFull;
- public String getName() { return name; }
- public Action isFull() { return new SimpleAction(name+"==1"); }
- public Action isEmpty() { return new SimpleAction(name+"==0"); }
- public Action doFill() { return new SimpleAction(name+"<=1;"); }
- public Action doDrain() { return new SimpleAction(name+"<=0;"); }
- public String doReset() { return name+"<="+(initiallyFull?"1":"0")+";"; }
- public StateWire(String name) { this(name, false); }
- public StateWire(String name, boolean initiallyFull) {
- this.name = name;
- this.initiallyFull = initiallyFull;
- statewires.put(name, this);
- }
- public void dump(PrintWriter pw) {
- pw.println(" reg "+name+";");
- pw.println(" initial "+name+"="+(initiallyFull?"1":"0")+";");
- }
- }
-
- public class Latch implements Assignable, Value {
- public final String name;
- public final int width;
- public Latch(String name, int width) {
- this.width = width;
- this.name = name;
- latches.put(name, this);
- }
- public String getVerilogName() { return name; }
- public Value getBits(int high, int low) { return new SimpleValue(getVerilogName(), high, low); }
- public Assignable getAssignableBits(int high, int low) { return new SimpleValue(getVerilogName(), high, low); }
- public String doReset() { return name+"<=0;"; }
- public void dump(PrintWriter pw) {
- pw.println(" reg ["+(width-1)+":0] "+name+";");
- pw.println(" initial "+name+"=0;");
- }
- }
-
- private abstract class Port implements Action, Assignable, Trigger {
- public final String name;
- public String getName() { return name; }
- public final int width;
- public int getWidth() { return width; }
- public boolean hasLatch = false;
- public boolean external;
- public Port(String name, int width, boolean external) {
- this.width = width;
- this.name = name;
- this.external = external;
- ports.put(name, this);
- if (external)
- portorder.add(name);
- }
- public String getVerilogName() { return name; }
- public String getAck() { return name+"_a"; }
- public String getReq() { return name+"_r"; }
- public abstract String getInterface();
- public abstract String getSimpleInterface();
- public abstract String getDeclaration();
- public abstract String getAssignments();
- }
-
- private class InstantiatedModule {
- public final Module module;
- public final int id;
- private final HashMap<String,Port> ports = new HashMap<String,Port>();
- public String getName() { return module.getName()+"_"+id; }
- public InstantiatedModule(Module module) {
- this.module = module;
- this.id = Module.this.id++;
- instantiatedModules.add(this);
- }
- public void dump(PrintWriter pw) {
- pw.println(" " + module.getName() + " " + getName() + "(clk, rst ");
- for(String s : module.portorder)
- pw.println(", " + getPort(s).getSimpleInterface());
- pw.println(" );");
- }
- public Port getPort(String name) {
- return (module.ports.get(name) instanceof SinkPort) ? getOutputPort(name) : getInputPort(name);
- }
- public SinkPort getInputPort(String name) {
- int width = module.getPort(name).getWidth();
- SinkPort port = (SinkPort)ports.get(name);
- if (port == null) {
- port = new SinkPort(getName()+"_"+name, width, false, "");
- ports.put(name, port);
- }
- return port;
- }
- public SourcePort getOutputPort(String name) {
- int width = module.getPort(name).getWidth();
- SourcePort port = (SourcePort)ports.get(name);
- if (port == null) {
- port = new SourcePort(getName()+"_"+name, width, false);
- ports.put(name, port);
- }
- return port;
- }
- }
-
- private class SourcePort extends Port implements Value {
- private SinkPort driven = null;
- public SourcePort(String name, int width, boolean external) {
- super(name, width, external); }
- public Value getBits(int high, int low) { return new SimpleValue(getVerilogName(), high, low); }
- public Assignable getAssignableBits(int high, int low) { return new SimpleValue(getVerilogName(), high, low); }
- public String getVerilogTrigger() { return " && " + getReq() + " && !"+getAck(); }
- public String getVerilogAction() { return getAck() + " <= 1;"; }
- public String getInterface() { return getReq()+", "+getAck()+"_, "+name+""; }
- public String getSimpleInterface() { return getReq()+", "+getAck()+", "+name+""; }
- public String getDeclaration() {
- StringBuffer sb = new StringBuffer();
- if (external) {
- sb.append("input " + name +"_r;\n");
- sb.append("output " + name +"_a_;\n");
- sb.append("input ["+(width-1)+":0]" + name +";\n");
- } else {
- sb.append("wire " + name +"_r;\n");
- sb.append("wire ["+(width-1)+":0]" + name +";\n");
- }
- if (!hasLatch) {
- sb.append("wire " + name +"_a;\n");
- } else {
- sb.append("reg " + name +"_a;\n");
- sb.append("initial " + name +"_a = 0;\n");
- }
- return sb.toString();
- }
- public String getAssignments() {
- StringBuffer sb = new StringBuffer();
- if (external)
- sb.append("assign " + name +"_a_ = " + name + "_a;\n");
- if (driven != null) {
- sb.append("assign " + driven.name +"_r = " + name + "_r;\n");
- sb.append("assign " + name +"_a = " + driven.name + "_a;\n");
- sb.append("assign " + driven.name +" = " + name + ";\n");
- }
- return sb.toString();
- }
- public void connect(SinkPort driven) {
- this.driven = driven;
- }
- }
- private class SinkPort extends Port {
- public final String resetBehavior;
- public Assignable getAssignableBits(int high, int low) { return new SimpleValue(getVerilogName(), high, low); }
- public String getVerilogAction() { return getReq() + " <= 1;"; }
- public String getVerilogTrigger() { return " && !" + getReq() + " && !"+getAck(); }
- public SinkPort(String name, int width, boolean external, String resetBehavior) {
- super(name, width, external); this.resetBehavior=resetBehavior; }
- public String getResetBehavior() { return resetBehavior; }
- public String getInterface() { return name+"_r_, "+name+"_a, "+name+"_"; }
- public String getSimpleInterface() { return name+"_r, "+name+"_a, "+name; }
- public String getDeclaration() {
- StringBuffer sb = new StringBuffer();
- if (external) {
- sb.append("output " + name +"_r_;\n");
- sb.append("input " + name +"_a;\n");
- sb.append("output ["+(width-1)+":0]" + name +"_;\n");
- } else {
- sb.append("wire " + name +"_a;\n");
- }
- if (!hasLatch) {
- sb.append("wire " + name +"_r;\n");
- sb.append("wire ["+(width-1)+":0]" + name +";\n");
- } else {
- sb.append("reg " + name +"_r;\n");
- sb.append("initial " + name +"_r = 0;\n");
- sb.append("reg ["+(width-1)+":0]" + name +";\n");
- sb.append("initial " + name +" = 0;\n");
- }
- return sb.toString();
- }
- public String getAssignments() {
- StringBuffer sb = new StringBuffer();
- if (external) {
- sb.append("assign " + name +"_r_ = " + name + "_r;\n");
- sb.append("assign " + name +"_ = " + name + ";\n");
- }
- return sb.toString();
- }
- }
-
- public void dump(PrintWriter pw, boolean fix) {
- pw.println("`include \"macros.v\"");
- pw.println("module "+name+"(clk, rst ");
- for(String name : portorder) {
- Port p = ports.get(name);
- pw.println(" , " + p.getInterface());
- }
- pw.println(" );");
- pw.println();
- pw.println(" input clk;");
- pw.println(" input rst;");
- for(String name : ports.keySet()) {
- Port p = ports.get(name);
- pw.println(" " + p.getDeclaration());
- }
- for(StateWire sw : statewires.values())
- sw.dump(pw);
- for(Latch l : latches.values())
- l.dump(pw);
- for(String name : ports.keySet()) {
- Port p = ports.get(name);
- pw.println(" " + p.getAssignments());
- }
- for(InstantiatedModule m : instantiatedModules) {
- m.dump(pw);
- }
- pw.println(precrap);
- pw.println("always @(posedge clk) begin");
- pw.println(" if (!rst) begin");
- for(Latch l : latches.values())
- pw.println(l.doReset());
- for(StateWire sw : statewires.values())
- pw.println(sw.doReset());
- for(Port p : ports.values()) {
- if (p instanceof SourcePort) {
- SourcePort ip = (SourcePort)p;
- if (ip.hasLatch)
- pw.println(ip.getAck()+" <=1;");
- } else {
- SinkPort op = (SinkPort)p;
- if (op.hasLatch)
- pw.println(op.getReq()+" <=0;");
- }
- }
- pw.println(" end else begin");
- for(Port p : ports.values()) {
- if (p instanceof SourcePort) {
- SourcePort ip = (SourcePort)p;
- if (ip.hasLatch)
- pw.println("if (!"+ip.getReq()+" && "+ip.getAck()+") "+ip.getAck()+"<=0;");
- } else {
- SinkPort op = (SinkPort)p;
- if (op.hasLatch)
- pw.println("if ("+op.getReq()+" && "+op.getAck()+") begin "+
- op.getReq()+"<=0; "+
- op.getResetBehavior()+" end");
- }
- }
- for(Event a : events) a.dump(pw, fix);
- pw.println(" begin end");
- pw.println(" end");
- pw.println(" end");
-
- pw.println(crap);
- pw.println("endmodule");
- }
-
- private class Event {
- private Object[] triggers;
- private Object[] actions;
- public Event(Object[] triggers, Object action) { this(triggers, new Object[] { action }); }
- public Event(Object[] triggers, Object[] actions) {
- Module.this.events.add(this);
- this.triggers = triggers;
- this.actions = actions;
- for(int i=0; i<triggers.length; i++)
- if (triggers[i] instanceof Port)
- ((Port)triggers[i]).hasLatch = true;
- }
- public void dump(PrintWriter pw, boolean fix) {
- pw.print("if (1");
- for(Object o : triggers) {
- if (o instanceof Trigger) pw.print(((Trigger)o).getVerilogTrigger());
- else pw.print(" && " + o);
- }
- pw.println(") begin ");
- for(Object a : actions) pw.println(((Action)a).getVerilogAction());
- if (fix) pw.println("end /*else*/ ");
- else pw.println("end else ");
- }
- }
- }
-
- public static void main(String[] s) throws Exception {
- String prefix = s[0];
- PrintWriter pw;
-
- 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_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) "+PUMP_NAME.verilogVal("p"));
- pw.flush();
- pw.close();
-
- mkfunnel("funnel", prefix);
- 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, fifo8);
- mkBox("inbox", true, prefix, fifo4, fifo8);
-
- Module fabric = new Module("fabric");
- fabric.createInputPort("horn_in", WIDTH_PACKET);
- fabric.createOutputPort("funnel_out", WIDTH_PACKET, "");
- mkRoot("root", prefix, fabric);
- }
-
- private static Module mkRoot(String name, String prefix, Module fabricm) throws Exception {
- Module root = new Module(name);
- Module.SourcePort in = root.createInputPort("in", 8);
- Module.SinkPort out = root.createOutputPort("out", 8, "");
- Module.InstantiatedModule fabric = root.new InstantiatedModule(fabricm);
- Module.SinkPort fabric_in = fabric.getInputPort("horn_in");
- Module.SourcePort fabric_out = fabric.getOutputPort("funnel_out");
- Module.Latch count = root.new Latch("count", 8);
- Module.Latch count_out = root.new Latch("count_out", 8);
- root.new Event(new Object[] { in, fabric_in },
- new Object[] { new SimpleAction(fabric_in.getName()+" <= ("+fabric_in.getName()+" << 8) | in;"),
- new SimpleAction("if (count >= 5) begin count <= 0; "+fabric_in.getName()+"_r <= 1; end else count <= count+1; "),
- in
- });
- root.new Event(new Object[] { out, fabric_out },
- new Object[] { new SimpleAction(out.getName()+" <= ("+fabric_out.getName()+">> (count_out*8));"),
- 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, true);
- pw.flush();
- return root;
- }
-
- private static Module mkfunnel(String name, String prefix) throws Exception {
- Module funnel = new Module(name);
- Module.SinkPort out = funnel.createOutputPort("out", WIDTH_PACKET, "");
- Module.SourcePort in1 = funnel.createInputPort("in1", WIDTH_PACKET);
- Module.SourcePort in2 = funnel.createInputPort("in2", WIDTH_PACKET);
- funnel.new Event(new Object[] { in1, out },
- new Action[] { in1, out,
- new AssignAction(out, in1) });
- funnel.new Event(new Object[] { in2, out },
- new Action[] { in2, out,
- new AssignAction(out, in2) });
- PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(prefix+"/"+name+".v")));
- funnel.dump(pw, true);
- pw.flush();
- return funnel;
- }
-
- private static Module mkfifo(String name, int len, Module instance, String prefix) throws Exception {
- Module fifo = new Module(name);
- Module.SourcePort in = fifo.createInputPort("in", WIDTH_PACKET);
- Module.SinkPort out = fifo.createOutputPort("out", WIDTH_PACKET, "");
- Module.InstantiatedModule[] stages = new Module.InstantiatedModule[len];
- if (len==0) {
- fifo.new Event(new Object[] { in, out },
- new Action[] { in, out, new AssignAction(out, in) });
- } else for(int i=0; i<=len; i++) {
- if (i<len) stages[i] = fifo.new InstantiatedModule(instance);
- Module.SourcePort driver = i==0 ? in : stages[i-1].getOutputPort("out");
- Module.SinkPort driven = i==len ? out : stages[i].getInputPort("in");
- driver.connect(driven);
- }
- PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(prefix+"/"+name+".v")));
- fifo.dump(pw, true);
- /*
- pw.println("`define FIFO_LENGTH " + len);
- //pw.println("`define NAME " + name);
- pw.println("`include \"macros.v\"");
- pw.println("module "+name+"(clk, rst ");
- pw.println(" , in_r, in_a_, in");
- pw.println(" , out_r_, out_a, out_);");
- BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("src/edu/berkeley/fleet/fpga/fifo.inc")));
- String s;
- while((s = br.readLine())!=null)
- pw.println(s);
- */
- pw.flush();
- return fifo;
- }
-
- public static void mkhorn(String name,
- String prefix,
- int top,
- int top_of_addr_field,
- int bot_of_addr_field,
- int bot) throws Exception {
- Module horn = new Module(name);
- Module.SourcePort in = horn.createInputPort("in", WIDTH_PACKET);
- Module.SinkPort out0 = horn.createOutputPort("out0", WIDTH_PACKET, "");
- Module.SinkPort out1 = horn.createOutputPort("out1", WIDTH_PACKET, "");
- String shifted_packet = "{ ";
- if (top_of_addr_field+1 < top) shifted_packet += " in["+top+":"+(top_of_addr_field+1)+"], ";
- shifted_packet += " (in["+(top_of_addr_field)+":"+bot_of_addr_field+"] >> 1) ";
- if (bot_of_addr_field > 0) shifted_packet += ", in["+(bot_of_addr_field-1)+":0] ";
- shifted_packet += " }";
- // same behavior as FLEET -- wait for both
- horn.new Event(new Object[] { in, out0, out1, "(in["+bot_of_addr_field+"]==0)" },
- new Action[] { in, out0, new AssignAction(out0, shifted_packet) });
- 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, true);
- pw.flush();
- }
-
- 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.SinkPort fabric_out = box.createOutputPort("fabric_out", WIDTH_PACKET, "");
- Module.InstantiatedModule dfifo = box.new InstantiatedModule(fifo);
- fabric_in.connect(dfifo.getInputPort("in"));
-
- Module.SourcePort dfifo_out = dfifo.getOutputPort("out");
- Module.SourcePort ship_out = null;
- if (!inbox) {
- ship_out = box.createInputPort("ship", WIDTH_WORD);
- ship_out.hasLatch = true;
- }
-
- Module.SinkPort ship_in = null;
- if (inbox) {
- ship_in = box.createOutputPort("ship", WIDTH_PACKET, "");
- ship_in.hasLatch = true;
- }
-
- Module.Latch ondeck = box.new Latch("ondeck", WIDTH_WORD);
- 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 loop_counter = box.new Latch("loop_counter", WIDTH_COUNTER_LITERAL);
- Module.Latch flag_a = box.new Latch("flag_a", 1);
- Module.Latch flag_b = box.new Latch("flag_b", 1);
- 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.StateWire isClogged = box.new StateWire("clogged", false);
- Module.StateWire isMassacreing = box.new StateWire("massacreing", false);
-
- Module.SinkPort token_out = fabric_out;
- Module.SourcePort token_in = dfifo_out;
- Module.SinkPort data_out = inbox ? ship_in : fabric_out;
- Module.SourcePort data_in = inbox ? dfifo_out : ship_out;
-
- Module.InstantiatedModule ififo = box.new InstantiatedModule(ififo_m);
- Module.SinkPort ififo_in = ififo.getInputPort("in");
- Module.SourcePort ififo_out = ififo.getOutputPort("out");
-
-
- // Massacre (when enqueued)
- box.new Event(
- new Object[] { ififo_out, "!`instruction_is_massacre("+ififo_out.getName()+")", isMassacreing.isFull() },
- new Action[] { ififo_out }
- );
- box.new Event(
- 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)", isMassacreing.isEmpty() },
- new Action[] { instr, ififo_in,
- new AssignAction(ififo_in, instr),
- isMassacreing.doFill(),
- ondeckFull.doDrain(),
- newMayProceed.doDrain(),
- new AssignAction(repeat_counter, "0"),
- new AssignAction(repcount2, "0"),
- new AssignAction(repcount, "0"),
- new AssignAction(loop_counter, "0"),
- }
- );
-
- // Clog (must be first)
- box.new Event(
- 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)", isMassacreing.isEmpty() },
- new Action[] { instr, isClogged.doDrain(), newMayProceed.doFill() }
- );
-
- // First Kill
- box.new Event(
- new Object[] { instr,
- "`instruction_is_kill(instr)",
- "!`instruction_is_unclog(instr)",
- ondeckFull.isFull(),
- isMassacreing.isEmpty()
- },
- new Action[] { instr,
- ondeckFull.doDrain(),
- new AssignAction(repeat_counter, "1"),
- new AssignAction(repcount2, "1"),
- newMayProceed.doFill()
- });
-
-
- // Enqueue
- box.new Event(
- 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(),
- "!`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()+")",
- new AssignAction(repcount2, "(repeat_counter==0?1:repeat_counter)")),
- new ConditionalAction("`instruction_is_normal("+ififo_out.getName()+")",
- new AssignAction(repeat_counter, "1")),
- }
- );
-
- // RepeatExecute
- box.new Event(
- new Object[] { doRepeat.isFull() },
- new Action[] { doRepeat.doDrain(),
- ondeckFull.doFill(),
- new AssignAction(repcount2, repcount)
- }
- );
-
- box.addPreCrap("wire [(`DATAWIDTH-1):0] data_latch_output;");
- box.addPreCrap("assign data_latch_output = " + (inbox ? data_out.getName() : "`packet_data("+data_out.getName()+")")+";");
-
- 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_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(),
- 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 Object[] { ondeckFull.isFull(),
- isMassacreing.isEmpty(),
- data_out,
- token_out,
- ififo_in,
- "!`instruction_is_kill(instr)",
- "(`instruction_is_normal(ondeck) || `instruction_is_literal_hi(ondeck) || `instruction_is_setflags(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[] { 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 || repcount2==`magic_standing_value", doRepeat.doFill()),
- new ConditionalAction("repcount2!=`magic_standing_value", new AssignAction(repcount, "repcount2-1")),
- new ConditionalAction("repcount2==`magic_standing_value", new AssignAction(repcount, "`magic_standing_value")),
- new ConditionalAction("`predicate_met(ondeck) && `instruction_is_literal(ondeck)",
- new AssignAction(data_latch, "`instruction_literal(ondeck)")),
- new ConditionalAction("`predicate_met(ondeck) && `instruction_is_literal_hi(ondeck)",
- new AssignAction(data_latch, "`instruction_literal_hi(ondeck,data_latch_output)")),
- new ConditionalAction("`predicate_met(ondeck) && `instruction_is_literal_lo(ondeck)",
- new AssignAction(data_latch, "`instruction_literal_lo(ondeck,data_latch_output)")),
- new ConditionalAction("`predicate_met(ondeck) && `instruction_is_setflags(ondeck)",
- new AssignAction(flag_a, "`new_flag_a(ondeck)")),
- new ConditionalAction("`predicate_met(ondeck) && `instruction_is_setflags(ondeck)",
- new AssignAction(flag_b, "`new_flag_b(ondeck)")),
- new ConditionalAction("`predicate_met(ondeck) && `instruction_bit_datain(ondeck)", data_in),
- new ConditionalAction("`predicate_met(ondeck) && `instruction_bit_dataout(ondeck)", data_out),
- new ConditionalAction("`predicate_met(ondeck) && `instruction_bit_tokenin(ondeck)", token_in),
- new ConditionalAction("`predicate_met(ondeck) && `instruction_bit_tokenout(ondeck)", token_out),
- new ConditionalAction("`predicate_met(ondeck) && `instruction_bit_latch(ondeck)",
- new AssignAction(data_latch, data_latch_input)),
- new ConditionalAction("`predicate_met(ondeck) && `instruction_path_from_data(ondeck)",
- new AssignAction(new SimpleAssignable("`packet_dest("+token_out.getName()+")"),
- PUMP_NAME.verilogVal(data_latch_input))),
- new ConditionalAction("`predicate_met(ondeck) && `instruction_path_from_literal(ondeck)",
- new AssignAction(new SimpleAssignable("`packet_dest("+token_out.getName()+")"),
- "`instruction_path_literal(ondeck)")),
- }
- );
- box.new Event(new Object[] { ondeckFull.isFull(),
- isMassacreing.isEmpty(),
- ififo_in,
- "!`instruction_is_kill(instr)",
- "`instruction_is_decr_loop(ondeck)"
- },
- new Action[] { new AssignAction(loop_counter, "loop_counter==0 ? 0 : (loop_counter-1)")
- }
- );
-
- 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_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 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_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_setflags(i) "+FLAGS.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 should_requeue(i) (loop_counter > 0)");
- pw.println("`define flag_a flag_a");
- pw.println("`define flag_b flag_b");
- pw.println("`define flag_z (loop_counter==0 ? 1 : 0)");
- pw.println("`define flag_s (data_latch_output["+(WIDTH_WORD-1)+"])");
- pw.println("`define predicate_met(i) 1");
- /*
- pw.println("`define predicate_met(i) ("+
- " " + P_A.verilog("i")+" ? `flag_a "+
- ":" + P_B.verilog("i")+" ? `flag_b "+
- ":" + P_Z.verilog("i")+" ? `flag_z "+
- ": 1"+
- ")");
- */
- pw.println("`define new_flag(x) ("+
- "( ((x >> 0) & 1) & !`flag_z) |" +
- "( ((x >> 1) & 1) & `flag_z) |" +
- "( ((x >> 2) & 1) & !`flag_s) |" +
- "( ((x >> 3) & 1) & `flag_s) |" +
- "( ((x >> 4) & 1) & !`flag_b) |" +
- "( ((x >> 5) & 1) & `flag_b) |" +
- "( ((x >> 6) & 1) & !`flag_a) |" +
- "( ((x >> 7) & 1) & `flag_a) | 0" +
- ")");
- pw.println("`define new_flag_a(i) `new_flag("+FLAGS_A.verilogVal("i")+")");
- pw.println("`define new_flag_b(i) `new_flag("+FLAGS_B.verilogVal("i")+")");
- pw.println("`define done_executing(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]) }");
-
- 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;
- }
-
-}
-
-
-
-
--- /dev/null
+package edu.berkeley.fleet.fpga;
+import edu.berkeley.fleet.api.*;
+import edu.berkeley.fleet.ies44.*;
+import edu.berkeley.fleet.*;
+import java.lang.reflect.*;
+import edu.berkeley.sbp.chr.*;
+import edu.berkeley.sbp.misc.*;
+import edu.berkeley.sbp.meta.*;
+import edu.berkeley.sbp.util.*;
+import java.util.*;
+import java.io.*;
+import static edu.berkeley.fleet.ies44.InstructionEncoder.*;
+import static edu.berkeley.fleet.verilog.Verilog.*;
+
+
+public class HornModule extends Module {
+
+ public HornModule() {
+ this(PACKET_DEST.width-1,
+ PACKET_DEST.valmaskmax,
+ PACKET_DEST.valmaskmin,
+ 0);
+ }
+ private HornModule(int top,
+ int top_of_addr_field,
+ int bot_of_addr_field,
+ int bot) {
+ super("horn");
+ Module.SourcePort in = createInputPort("in", WIDTH_PACKET);
+ Module.SinkPort out0 = createOutputPort("out0", WIDTH_PACKET, "");
+ Module.SinkPort out1 = createOutputPort("out1", WIDTH_PACKET, "");
+ Module.Latch out = new Module.Latch("out", WIDTH_PACKET);
+ out0.forceNoLatch = true;
+ out1.forceNoLatch = true;
+ addCrap("assign out0 = out;");
+ addCrap("assign out1 = out;");
+ String shifted_packet = "{ ";
+ if (top_of_addr_field < top) shifted_packet += " in["+top+":"+(top_of_addr_field+1)+"], ";
+ shifted_packet += " (in["+(top_of_addr_field)+":"+bot_of_addr_field+"] >> 1) ";
+ if (bot_of_addr_field > 0) shifted_packet += ", in["+(bot_of_addr_field-1)+":0] ";
+ shifted_packet += " }";
+ new Event(new Object[] { in, out0, out1, "(in["+bot_of_addr_field+"]==0)" },
+ new Action[] { in, out0, new AssignAction(out, shifted_packet) });
+ new Event(new Object[] { in, out0, out1, "(in["+bot_of_addr_field+"]==1)" },
+ new Action[] { in, out1, new AssignAction(out, shifted_packet) });
+ }
+
+ public static class HornInstance extends Module.InstantiatedModule implements FabricElement {
+ private FabricElement out0;
+ private FabricElement out1;
+ public void addInput(FabricElement in, Module.Port source) { source.connect(getInputPort("in")); }
+ public Module.Port getOutputPort() { throw new RuntimeException("horn has multiple outputs"); }
+ public Module.Port getInputPort() { return getInputPort("in"); }
+ public HornInstance(Module thisModule, FabricElement out0, FabricElement out1) {
+ super(thisModule, new HornModule());
+ this.out0 = out0;
+ this.out1 = out1;
+ out0.addInput(this, getOutputPort("out0"));
+ out1.addInput(this, getOutputPort("out1"));
+ }
+ public void addOutput(FabricElement out, Module.Port outPort) { throw new RuntimeException(); }
+ public FpgaPath getPath(FabricElement dest, BitVector signal) {
+ FpgaPath path0 = out0==null ? null : out0.getPath(dest, signal);
+ FpgaPath path1 = out1==null ? null : out1.getPath(dest, signal);
+ if (path0 != null) path0 = path0.prepend(false);
+ if (path1 != null) path1 = path1.prepend(true);
+ if (path0==null) return path1;
+ if (path1==null) return path0;
+ if (path0.getLatencyMetric() < path1.getLatencyMetric()) return path0;
+ // FIXME: choke if latency metrics equal?
+ // FIXME: determinism of path-search?
+ return path1;
+ }
+ }
+
+}
import java.net.*;
import java.util.*;
+// FIXME: accept connections, but stall, during programming
public class Server {
+ static boolean sign = false;
+
static long jarFileTime = 0;
static long bitFileTime = 0;
while(true) {
try {
Socket s = ss.accept();
+ System.out.println("accept!");
new Handler(s).start();
} catch (Exception e) {
e.printStackTrace();
}
public static String pass_string = "password=security_is_for_wimps ";
-
static class Handler extends Thread {
private Socket socket;
boolean closed = false;
this.sp = new RXTXPort("/dev/ttyS0");
sp.setInputBufferSize(0);
sp.setOutputBufferSize(0);
- sp.setSerialPortParams(9600, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
+ sp.setSerialPortParams(38400, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
sp.setFlowControlMode(sp.FLOWCONTROL_RTSCTS_IN | sp.FLOWCONTROL_RTSCTS_OUT);
try {
_run();
}
public void _run() {
try {
- final InputStream is = socket.getInputStream();
+ final InputStream is = new BufferedInputStream(socket.getInputStream());
byte[] buf = new byte[1024];
StringBuffer sb = new StringBuffer();
while(true) {
}
System.err.println("login string: " + sb.toString());
if (!sb.toString().startsWith(pass_string)) return;
-
- //try { Thread.sleep(500); } catch(Exception e) { }
- final OutputStream os = socket.getOutputStream();
-
- System.out.println("sending breaks");
- for(int i=0; i<2; i++) {
- sp.sendBreak(100);
- Thread.sleep(100);
- }
- System.out.println("done sending breaks");
+ final OutputStream os = new BufferedOutputStream(socket.getOutputStream());
+ System.err.println("sending breaks...");
+ sp.sendBreak(100);
final OutputStream fos = sp.getOutputStream();
- final InputStream fis = sp.getInputStream();
+ final InputStream fis = new BufferedInputStream(sp.getInputStream());
+ sign = false;
System.err.println("sending instructions...");
new Thread() {
public void run() {
try {
- byte[] buf = new byte[1024];
while(true) {
- int numread = is.read(buf, 0, buf.length);
- if (numread == -1) break;
- fos.write(buf, 0, numread);
- fos.flush();
+ int r = is.read();
+ if (r == -1) break;
+ fos.write(r);
+ if (!sign) {
+ fos.flush();
+ Thread.sleep(100);
+ sign = true;
+ }
}
+ fos.flush();
} catch (Exception e) { throw new RuntimeException(e);
} finally {
System.err.println("closing...");
}
}.start();
- /*
- int last = 0;
- for(int j=0; j<3; j++)
- while(true) {
- int i = fis.read();
- if (i==-1) return;
- System.out.println("leader byte: 0x" + Integer.toString(i, 16) + " '"+((char)i)+"'");
- if (((char)last) == 'o' && ((char)i) == 'k') break;
- last = i;
- }
- */
System.err.println("reading back...");
while(true) {
long result = 0;
int val = 0;
+ boolean hit=false;
for(int i=0; i<6; i++) {
int k = 0;
while(!closed && fis.available()==0) {
System.err.println("sleep");
k = 0;
}
+ if (k==10) os.flush();
Thread.sleep(10);
}
- if (closed) return;
+ if (closed) { os.flush(); return; }
val = fis.read();
+ if (!sign) {
+ System.err.println("leader byte: 0x" + Integer.toString(val, 16) + " '"+((char)val)+"'");
+ continue;
+ }
if (val==-1) break;
System.err.println("byte: 0x"+Integer.toString(val & 0xff, 16));
os.write((byte)val);
- os.flush();
result |= ((long)val) << (i * 8);
}
if (val==-1) break;
System.err.print(Long.toString(result, 16));
System.err.println();
}
+ os.flush();
System.err.println("done.");
} catch (Exception e) { throw new RuntimeException(e);
}
}
-}
\ No newline at end of file
+}
wire sio_ce;
wire sio_ce_x4;
- sasc_brg sasc_brg(clk, ser_rst, 10, 217, sio_ce, sio_ce_x4);
+ //sasc_brg sasc_brg(clk, ser_rst, 10, 217, sio_ce, sio_ce_x4);
+ sasc_brg sasc_brg(clk, ser_rst, 8, 65, sio_ce, sio_ce_x4);
sasc_top sasc_top(clk, ser_rst,
fpga_0_RS232_Uart_1_sin_pin,
fpga_0_RS232_Uart_1_sout_pin,
wire [7:0] root_in_d;
wire [7:0] root_out_d;
-
- root my_root(clk, rst && !break,
+ /*
+ * There is some very weird timing thing going on here; we need to
+ * hold reset low for more than one clock in order for it to propagate
+ * all the way to the docks.
+ */
+ root my_root(clk, rst && !break_o,
root_in_r, root_in_a, root_in_d,
root_out_r, root_out_a, root_out_d);
/*
if (break) begin
root_out_a_reg = 0;
data_to_host_write_enable_reg <= 0;
-/*
+
end else if (break_done) begin
data_to_host_write_enable_reg <= 1;
data_to_host_r <= 111;
data_to_host_write_enable_reg <= 1;
data_to_host_r <= 107;
send_k <= 0;
-*/
+
end else if (root_out_r && !root_out_a_reg && !data_to_host_full) begin
data_to_host_write_enable_reg <= 1;
set -tmpdir ./tmp
set -xsthdpdir ./xst
run
--ifn main.prj -ifmt mixed -ofn main -ofmt NGC -p xc4vfx60 -top main -opt_mode Speed -opt_level 1 -iuc NO -lso main.lso -keep_hierarchy NO -rtlview Yes -glob_opt AllClockNets -read_cores YES -write_timing_constraints NO -cross_clock_analysis NO -hierarchy_separator / -bus_delimiter <> -case maintain -slice_utilization_ratio 100 -verilog2001 YES -fsm_extract Yes -fsm_encoding Auto -safe_implementation No -fsm_style lut -ram_extract Yes -ram_style Auto -rom_extract Yes -mux_style Auto -decoder_extract YES -priority_extract YES -shreg_extract YES -shift_extract YES -xor_collapse YES -rom_style Auto -mux_extract YES -resource_sharing YES -mult_style auto -iobuf YES -max_fanout 500 -bufg 1 -register_duplication YES -register_balancing No -slice_packing Yes -optimize_primitives Yes -tristate2logic Yes -use_clock_enable Yes -use_sync_set Yes -use_sync_reset Yes -iob auto -equivalent_register_removal YES -slice_utilization_ratio_maxmargin 5
+-ifn main.prj -ifmt mixed -ofn main -ofmt NGC -p xc4vfx60 -top main -opt_mode Area -opt_level 1 -iuc NO -lso main.lso -keep_hierarchy NO -rtlview Yes -glob_opt AllClockNets -read_cores YES -write_timing_constraints NO -cross_clock_analysis NO -hierarchy_separator / -bus_delimiter <> -case maintain -slice_utilization_ratio 100 -verilog2001 YES -fsm_extract Yes -fsm_encoding Auto -safe_implementation No -fsm_style lut -ram_extract Yes -ram_style Auto -rom_extract Yes -mux_style Auto -decoder_extract YES -priority_extract YES -shreg_extract YES -shift_extract YES -xor_collapse YES -rom_style Auto -mux_extract YES -resource_sharing YES -mult_style auto -iobuf YES -max_fanout 500 -bufg 1 -register_duplication YES -register_balancing No -slice_packing Yes -optimize_primitives Yes -tristate2logic Yes -use_clock_enable Yes -use_sync_set Yes -use_sync_reset Yes -iob auto -equivalent_register_removal YES -slice_utilization_ratio_maxmargin 5
--- /dev/null
+package edu.berkeley.fleet.verilog;
+import edu.berkeley.fleet.api.*;
+import edu.berkeley.fleet.ies44.*;
+import edu.berkeley.fleet.*;
+import java.lang.reflect.*;
+import edu.berkeley.sbp.chr.*;
+import edu.berkeley.sbp.misc.*;
+import edu.berkeley.sbp.meta.*;
+import edu.berkeley.sbp.util.*;
+import java.util.*;
+import java.io.*;
+import static edu.berkeley.fleet.ies44.InstructionEncoder.*;
+
+public class Verilog {
+
+ public static class SimpleValue implements Value {
+ public final String s;
+ public SimpleValue(String s) { this.s = s; }
+ public SimpleValue(String s, int high, int low) { this.s = s+"["+high+":"+low+"]"; }
+ public Value getBits(int high, int low) { return new SimpleValue(s, high, low); }
+ public Assignable getAssignableBits(int high, int low) { return new SimpleValue(s, high, low); }
+ public String getVerilogName() { return s; }
+ public String toString() { return s; }
+ }
+
+ public static interface Action {
+ public String getVerilogAction();
+ }
+
+ public static interface Trigger {
+ public String getVerilogTrigger();
+ }
+
+ public static interface Assignable {
+ public String getVerilogName();
+ public Assignable getAssignableBits(int high, int low);
+ }
+
+ public static interface Value extends Assignable {
+ public String getVerilogName();
+ public Value getBits(int high, int low);
+ }
+
+ public static class ConditionalAction implements Action {
+ public String condition;
+ public Action action;
+ public ConditionalAction(String condition, Action action) {
+ this.condition = condition;
+ this.action = action;
+ }
+ public String toString() { return getVerilogAction(); }
+ public String getVerilogAction() { return "if ("+condition+") begin "+action.getVerilogAction()+" end"; }
+ }
+
+ public static class ConditionalTrigger implements Trigger {
+ public String condition;
+ public Trigger trigger;
+ public ConditionalTrigger(String condition, Trigger trigger) {
+ this.condition = condition;
+ this.trigger = trigger;
+ if (trigger instanceof Module.Port)
+ ((Module.Port)trigger).hasLatch = true;
+ }
+ public String getVerilogTrigger() {
+ return "&& (("+condition+") ? (1 " + trigger.getVerilogTrigger() + ") : 1)";
+ }
+ }
+
+ public static class SimpleAssignable implements Assignable {
+ public final String s;
+ public SimpleAssignable(String s) { this.s = s; }
+ public String getVerilogName() { return s; }
+ public Assignable getAssignableBits(int high, int low) { return new SimpleValue(s, high, low); }
+ }
+
+ public static class AssignAction implements Action {
+ public String left;
+ public String right;
+ public AssignAction(Assignable left, Value right) {
+ this.left = left.getVerilogName();
+ this.right = right.getVerilogName().toString();
+ }
+ public AssignAction(Assignable left, String right) {
+ this.left = left.getVerilogName();
+ this.right = right;
+ }
+ public String getVerilogAction() { return left + "<=" + right + ";"; }
+ public String toString() { return getVerilogAction(); }
+ }
+
+ public static class SimpleAction implements Action {
+ public final String verilog;
+ public SimpleAction(String verilog) { this.verilog = verilog; }
+ public String getVerilogAction() { return verilog; }
+ public String toString() { return verilog; }
+ }
+
+ public static class Module {
+ public void dump(String prefix) throws IOException {
+ PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(prefix+"/bitfields.v")));
+ pw.println("`define DATAWIDTH "+WIDTH_WORD);
+ pw.println("`define CODEBAG_SIZE_BITS "+CBD_SIZE.valmaskwidth);
+ pw.println("`define INSTRUCTION_WIDTH "+WIDTH_WORD);
+ pw.println("`define packet_token(p) "+PACKET_TOKEN.verilogVal("p"));
+ pw.println("`define packet_data(p) "+PACKET_DATA.verilogVal("p"));
+ pw.println("`define packet_dest(p) "+PACKET_DEST.verilogVal("p"));
+ pw.println("`define instruction_dest(p) "+DISPATCH_PATH.verilogVal("p"));
+ pw.flush();
+ pw.close();
+ pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(prefix+"/"+name+".v")));
+ dump(pw, true);
+ pw.flush();
+ }
+ public int id = 0;
+ public final String name;
+ public String getName() { return name; }
+ public Port getPort(String name) { return ports.get(name); }
+
+ public HashSet<InstantiatedModule> instantiatedModules = new HashSet<InstantiatedModule>();
+ public final ArrayList<Event> events = new ArrayList<Event>();
+
+ // FIXME: always-alphabetical convention?
+ public final HashMap<String,Port> ports = new HashMap<String,Port>();
+ public final ArrayList<String> portorder = new ArrayList<String>();
+ public final HashMap<String,StateWire> statewires = new HashMap<String,StateWire>();
+ public final HashMap<String,Latch> latches = new HashMap<String,Latch>();
+
+ public StringBuffer crap = new StringBuffer();
+ public StringBuffer precrap = new StringBuffer();
+ public void addCrap(String s) { crap.append(s); crap.append('\n'); }
+ public void addPreCrap(String s) { precrap.append(s); precrap.append('\n'); }
+ public void addPreCrap0(String s) { precrap.append(s); }
+
+ public Module(String name) {
+ this.name = name;
+ }
+
+ public SourcePort createInputPort(String name, int width) {
+ if (ports.get(name)!=null) throw new RuntimeException();
+ return new SourcePort(name, width, true);
+ }
+ public SourcePort getInputPort(String name) {
+ SourcePort ret = (SourcePort)ports.get(name);
+ if (ret==null) throw new RuntimeException();
+ return ret;
+ }
+ public SinkPort createOutputPort(String name, int width, String resetBehavior) {
+ if (ports.get(name)!=null) throw new RuntimeException();
+ return new SinkPort(name, width, true, resetBehavior);
+ }
+ public SinkPort createWirePort(String name, int width) {
+ if (ports.get(name)!=null) throw new RuntimeException();
+ return new SinkPort(name, width, false, "");
+ }
+ public SourcePort createWireSourcePort(String name, int width) {
+ if (ports.get(name)!=null) throw new RuntimeException();
+ return new SourcePort(name, width, false);
+ }
+ public SinkPort getOutputPort(String name) {
+ SinkPort ret = (SinkPort)ports.get(name);
+ if (ret==null) throw new RuntimeException();
+ return ret;
+ }
+
+ public class StateWire {
+ public final String name;
+ public final boolean initiallyFull;
+ public String getName() { return name; }
+ public Action isFull() { return new SimpleAction(name+"==1"); }
+ public Action isEmpty() { return new SimpleAction(name+"==0"); }
+ public Action doFill() { return new SimpleAction(name+"<=1;"); }
+ public Action doDrain() { return new SimpleAction(name+"<=0;"); }
+ public String doReset() { return name+"<="+(initiallyFull?"1":"0")+";"; }
+ public StateWire(String name) { this(name, false); }
+ public StateWire(String name, boolean initiallyFull) {
+ this.name = name;
+ this.initiallyFull = initiallyFull;
+ statewires.put(name, this);
+ }
+ public void dump(PrintWriter pw) {
+ pw.println(" reg "+name+";");
+ pw.println(" initial "+name+"="+(initiallyFull?"1":"0")+";");
+ }
+ }
+
+ public class Latch implements Assignable, Value {
+ public final String name;
+ public final int width;
+ public final long initial;
+ public Latch(String name, int width) { this(name, width, 0); }
+ public Latch(String name, int width, long initial) {
+ this.width = width;
+ this.name = name;
+ this.initial = initial;
+ latches.put(name, this);
+ }
+ public String getVerilogName() { return name; }
+ public Value getBits(int high, int low) { return new SimpleValue(getVerilogName(), high, low); }
+ public Assignable getAssignableBits(int high, int low) { return new SimpleValue(getVerilogName(), high, low); }
+ public String doReset() { return name+"<="+initial+";"; }
+ public void dump(PrintWriter pw) {
+ pw.println(" reg ["+(width-1)+":0] "+name+";");
+ pw.println(" initial "+name+"="+initial+";");
+ }
+ }
+
+ public abstract class Port implements Action, Assignable, Trigger {
+ public abstract String doReset();
+ public final String name;
+ public String getName() { return name; }
+ public final int width;
+ public int getWidth() { return width; }
+ public boolean hasLatch = false;
+ public boolean external;
+ public Port(String name, int width, boolean external) {
+ this.width = width;
+ this.name = name;
+ this.external = external;
+ ports.put(name, this);
+ if (external)
+ portorder.add(name);
+ }
+ public String getVerilogName() { return name; }
+ public String getAck() { return name+"_a"; }
+ public String getReq() { return name+"_r"; }
+ public abstract String getInterface();
+ public abstract String getSimpleInterface();
+ public abstract String getDeclaration();
+ public abstract String getAssignments();
+ public abstract void connect(SinkPort driven);
+ }
+
+ public static class InstantiatedModule {
+ public final Module module;
+ public final Module thisModule;
+ public final int id;
+ public final HashMap<String,Port> ports = new HashMap<String,Port>();
+ public String getName() { return module.getName()+"_"+id; }
+ public InstantiatedModule(Module thisModule, Module module) {
+ this.thisModule = thisModule;
+ this.module = module;
+ this.id = thisModule.id++;
+ thisModule.instantiatedModules.add(this);
+ }
+ public void dump(PrintWriter pw) {
+ pw.println(" " + module.getName() + " " + getName() + "(clk, rst ");
+ for(String s : module.portorder)
+ pw.println(", " + getPort(s).getSimpleInterface());
+ pw.println(" );");
+ }
+ public Port getPort(String name) {
+ return (module.ports.get(name) instanceof SinkPort) ? getOutputPort(name) : getInputPort(name);
+ }
+ public SinkPort getInputPort(String name) {
+ int width = module.getPort(name).getWidth();
+ SinkPort port = (SinkPort)ports.get(name);
+ if (port == null) {
+ port = thisModule.new SinkPort(getName()+"_"+name, width, false, "");
+ ports.put(name, port);
+ }
+ return port;
+ }
+ public SourcePort getOutputPort(String name) {
+ int width = module.getPort(name).getWidth();
+ SourcePort port = (SourcePort)ports.get(name);
+ if (port == null) {
+ port = thisModule.new SourcePort(getName()+"_"+name, width, false);
+ ports.put(name, port);
+ }
+ return port;
+ }
+ }
+
+ public class SourcePort extends Port implements Value {
+ public SinkPort driven = null;
+ public SourcePort(String name, int width, boolean external) {
+ super(name, width, external); }
+ public Value getBits(int high, int low) { return new SimpleValue(getVerilogName(), high, low); }
+ public Assignable getAssignableBits(int high, int low) { return new SimpleValue(getVerilogName(), high, low); }
+ public String getVerilogTrigger() { return " && " + getReq() + " && !"+getAck(); }
+ public String getVerilogAction() { return getAck() + " <= 1;"; }
+ public String getInterface() { return getReq()+", "+getAck()+"_, "+name+""; }
+ public String getSimpleInterface() { return getReq()+", "+getAck()+", "+name+""; }
+ public String getDeclaration() {
+ StringBuffer sb = new StringBuffer();
+ if (external) {
+ sb.append("input " + name +"_r;\n");
+ sb.append("output " + name +"_a_;\n");
+ sb.append("input ["+(width-1)+":0]" + name +";\n");
+ } else {
+ sb.append("wire " + name +"_r;\n");
+ sb.append("wire ["+(width-1)+":0]" + name +";\n");
+ }
+ if (!hasLatch) {
+ sb.append("wire " + name +"_a;\n");
+ } else {
+ sb.append("reg " + name +"_a;\n");
+ sb.append("initial " + name +"_a = 0;\n");
+ }
+ return sb.toString();
+ }
+ public String doReset() { return hasLatch ? name+"_a<=1;" : ""; }
+ public String getAssignments() {
+ StringBuffer sb = new StringBuffer();
+ if (external)
+ sb.append("assign " + name +"_a_ = " + name + "_a;\n");
+ if (driven != null) {
+ sb.append("assign " + driven.name +"_r = " + name + "_r;\n");
+ sb.append("assign " + name +"_a = " + driven.name + "_a;\n");
+ sb.append("assign " + driven.name +" = " + name + ";\n");
+ }
+ return sb.toString();
+ }
+ public void connect(SinkPort driven) {
+ this.driven = driven;
+ }
+ }
+ public class SinkPort extends Port {
+ public boolean forceNoLatch = false;
+ public SinkPort driven = null;
+ public final String resetBehavior;
+ public Assignable getAssignableBits(int high, int low) { return new SimpleValue(getVerilogName(), high, low); }
+ public String getVerilogAction() { return getReq() + " <= 1;"; }
+ public String getVerilogTrigger() { return " && !" + getReq() + " && !"+getAck(); }
+ public SinkPort(String name, int width, boolean external, String resetBehavior) {
+ super(name, width, external); this.resetBehavior=resetBehavior; }
+ public String getResetBehavior() { return resetBehavior; }
+ public String getInterface() { return name+"_r_, "+name+"_a, "+name+"_"; }
+ public String getSimpleInterface() { return name+"_r, "+name+"_a, "+name; }
+ public String getDeclaration() {
+ StringBuffer sb = new StringBuffer();
+ if (external) {
+ sb.append("output " + name +"_r_;\n");
+ sb.append("input " + name +"_a;\n");
+ sb.append("output ["+(width-1)+":0]" + name +"_;\n");
+ } else {
+ sb.append("wire " + name +"_a;\n");
+ }
+
+ if (forceNoLatch) {
+ sb.append("reg " + name +"_r;\n");
+ sb.append("initial " + name +"_r = 0;\n");
+ sb.append("wire ["+(width-1)+":0]" + name +";\n");
+ } else if (!hasLatch) {
+ sb.append("wire " + name +"_r;\n");
+ sb.append("wire ["+(width-1)+":0]" + name +";\n");
+ } else {
+ sb.append("reg " + name +"_r;\n");
+ sb.append("initial " + name +"_r = 0;\n");
+ sb.append("reg ["+(width-1)+":0]" + name +";\n");
+ sb.append("initial " + name +" = 0;\n");
+ }
+ return sb.toString();
+ }
+ public String doReset() {
+ return forceNoLatch
+ ? name+"_r<=0;"
+ : hasLatch
+ ? (name+"_r<=0; "+name+"<=0;")
+ : "";
+ }
+ public String getAssignments() {
+ StringBuffer sb = new StringBuffer();
+ if (external) {
+ sb.append("assign " + name +"_r_ = " + name + "_r;\n");
+ sb.append("assign " + name +"_ = " + name + ";\n");
+ }
+ if (driven != null) {
+ sb.append("assign " + driven.name +"_r = " + name + "_r;\n");
+ sb.append("assign " + name +"_a = " + driven.name + "_a;\n");
+ sb.append("assign " + driven.name +" = " + name + ";\n");
+ }
+ return sb.toString();
+ }
+ public void connect(SinkPort driven) {
+ this.driven = driven;
+ }
+ }
+
+ public void dump(PrintWriter pw, boolean fix) {
+ pw.println("`include \"macros.v\"");
+ pw.println("module "+name+"(clk, rst ");
+ for(String name : portorder) {
+ Port p = ports.get(name);
+ pw.println(" , " + p.getInterface());
+ }
+ pw.println(" );");
+ pw.println();
+ pw.println(" input clk;");
+ pw.println(" input rst;");
+ for(String name : ports.keySet()) {
+ Port p = ports.get(name);
+ pw.println(" " + p.getDeclaration());
+ }
+ for(StateWire sw : statewires.values())
+ sw.dump(pw);
+ for(Latch l : latches.values())
+ l.dump(pw);
+ for(String name : ports.keySet()) {
+ Port p = ports.get(name);
+ pw.println(" " + p.getAssignments());
+ }
+ for(InstantiatedModule m : instantiatedModules) {
+ m.dump(pw);
+ }
+ pw.println(precrap);
+ pw.println("always @(posedge clk) begin");
+ pw.println(" if (!rst) begin");
+ for(Latch l : latches.values())
+ pw.println(l.doReset());
+ for(StateWire sw : statewires.values())
+ pw.println(sw.doReset());
+ for(Port p : ports.values())
+ pw.println(p.doReset());
+ pw.println(" end else begin");
+ for(Port p : ports.values()) {
+ if (p instanceof SourcePort) {
+ SourcePort ip = (SourcePort)p;
+ if (ip.hasLatch)
+ pw.println("if (!"+ip.getReq()+" && "+ip.getAck()+") "+ip.getAck()+"<=0;");
+ } else {
+ SinkPort op = (SinkPort)p;
+ if (op.hasLatch)
+ pw.println("if ("+op.getReq()+" && "+op.getAck()+") begin "+
+ op.getReq()+"<=0; "+
+ op.getResetBehavior()+" end");
+ }
+ }
+ for(Event a : events) a.dump(pw, fix);
+ pw.println(" begin end");
+ pw.println(" end");
+ pw.println(" end");
+
+ pw.println(crap);
+ pw.println("endmodule");
+ }
+
+ public class Event {
+ public Object[] triggers;
+ public Object[] actions;
+ public Event(Object[] triggers, Object action) { this(triggers, new Object[] { action }); }
+ public Event(Object[] triggers, Object[] actions) {
+ Module.this.events.add(this);
+ this.triggers = triggers;
+ this.actions = actions;
+ for(int i=0; i<triggers.length; i++)
+ if (triggers[i] instanceof Port)
+ ((Port)triggers[i]).hasLatch = true;
+ }
+ public void dump(PrintWriter pw, boolean fix) {
+ pw.print("if (1");
+ for(Object o : triggers) {
+ if (o instanceof Trigger) pw.print(((Trigger)o).getVerilogTrigger());
+ else pw.print(" && " + o);
+ }
+ pw.println(") begin ");
+ for(Object a : actions) pw.println(((Action)a).getVerilogAction());
+ if (fix) pw.println("end /*else*/ ");
+ else pw.println("end else ");
+ }
+ }
+ }
+}
package edu.berkeley.fleet.ies44;
+import java.io.*;
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 edu.berkeley.fleet.api.Instruction.Set;
+import static edu.berkeley.fleet.api.Instruction.Set.*;
import static edu.berkeley.fleet.api.Instruction.*;
-import static edu.berkeley.fleet.api.Instruction.Counter.*;
+import static edu.berkeley.fleet.api.Predicate.*;
-public abstract class InstructionEncoder {
- 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_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........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................");
- 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 P_A = new Mask(".............00......................");
- public static final Mask P_B = new Mask(".............10......................");
- public static final Mask P_Z = new Mask(".............01......................");
- public static final Mask P_ALWAYS = new Mask(".............11......................");
- public static final Mask MOVE = new Mask("...............001...................");
- 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 TOP_HALF_LITERAL = new Mask("vvvvvvvvvvvvvvvvvv...................");
- public static final Mask BOT_HALF_LITERAL = new Mask("..................vvvvvvvvvvvvvvvvvvv");
- public static final Mask TOP_HALF_ONE = new Mask("111111111111111111...................");
- public static final Mask BOT_HALF_ONE = new Mask("..................1111111111111111111");
- 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 LITERAL_LOW_ZERO = new Mask("...............100...................");
- public static final Mask LITERAL_LOW_ONE = new Mask("...............101...................");
- public static final Mask LITERAL_HIGH_ZERO = new Mask("...............110...................");
- public static final Mask LITERAL_HIGH_ONE = new Mask("...............111...................");
- public static final Mask PUMP_NAME = new Mask("vvvvvvvvvvv..........................");
+public abstract class InstructionEncoder {
+ public static final Mask PACKET_TOKEN = new Mask("v.................................................");
+ public static final Mask PACKET_DATA = new Mask(".vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv............");
+ public static final Mask PACKET_SIGNAL = new Mask("......................................v...........");
+ public static final Mask PACKET_DEST = new Mask(".......................................vvvvvvvvvvv");
+
+ public static final Mask CBD_SIZE = new Mask("...............................vvvvvv");
+ public static final Mask CBD_OFFSET = new Mask("vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv......");
+
+ public static final int WIDTH_WORD = PACKET_DATA.valmaskwidth;
+ public static final int WIDTH_PACKET = PACKET_TOKEN.width;
+
+ public static final Mask DISPATCH_PATH = new Mask("vvvvvvvvvvv..........................");
+ public static final Mask I = new Mask("...........1.........................");
+ public static final Mask OS = new Mask("............1........................");
+ public static final Mask P = new Mask(".............vvv.....................");
+ public static final Mask P_NOT_A = new Mask(".............000.....................");
+ public static final Mask P_A = new Mask(".............001.....................");
+ public static final Mask P_NOT_B = new Mask(".............010.....................");
+ public static final Mask P_B = new Mask(".............011.....................");
+ public static final Mask P_NOT_C = new Mask(".............100.....................");
+ public static final Mask P_C = new Mask(".............101.....................");
+ public static final Mask P_OLC = new Mask(".............110.....................");
+ public static final Mask P_ALWAYS = new Mask(".............111.....................");
+
+ public static final Mask SHIFT = new Mask("................00vvvvvvvvvvvvvvvvvvv");
+
+ public static final Mask TAIL = new Mask("................11...................");
+
+ public static final Mask MOVE = new Mask("................01...................");
+ 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_IMMEDIATE = new Mask(".......................1vvvvvvvvvvvvv");
+ public static final Mask PATH_DATA = new Mask(".......................01............");
+ public static final Mask PATH_NOCHANGE = new Mask(".......................00............");
+
+ public static final Mask SET = new Mask("................10...................");
+
+ public static final Mask SET_OLC_FROM_IMMEDIATE = new Mask("................1010000100.....vvvvvv");
+ public static final Mask SET_OLC_FROM_DATA_LATCH = new Mask("................1010000010...........");
+ public static final Mask SET_OLC_FROM_OLC_MINUS_ONE = new Mask("................1010000001...........");
+
+ public static final Mask SET_ILC_FROM_IMMEDIATE = new Mask("................1001000100.....vvvvvv");
+ public static final Mask SET_ILC_FROM_INFINITY = new Mask("................1001000010...........");
+ public static final Mask SET_ILC_FROM_DATA_LATCH = new Mask("................1001000001...........");
+
+ public static final Mask SET_IMMEDIATE = new Mask("................1000100.vvvvvvvvvvvvv");
+ public static final Mask SET_IMMEDIATE_EXTEND = new Mask("................1000100v.............");
+
+ public static final Mask SET_FLAGS = new Mask("................1000010..............");
+ public static final Mask SET_FLAGS_A = new Mask("................1000010..vvvvvv......");
+ public static final Mask SET_FLAGS_B = new Mask("................1000010........vvvvvv");
+ public static final Mask SET_FLAGS_VALUE_A = new Mask("1.....");
+ public static final Mask SET_FLAGS_VALUE_NOT_A = new Mask(".1....");
+ public static final Mask SET_FLAGS_VALUE_B = new Mask("..1...");
+ public static final Mask SET_FLAGS_VALUE_NOT_B = new Mask("...1..");
+ public static final Mask SET_FLAGS_VALUE_C = new Mask("....1.");
+ public static final Mask SET_FLAGS_VALUE_NOT_C = new Mask(".....1");
+
+ public static final Mask SET_TAPL_FROM_IMMEDIATE = new Mask("................1000001.vvvvvvvvvvvvv");
+
+
+ public static final long DataLatch_WIDTH = SET_IMMEDIATE.valmaskmax-SET_IMMEDIATE.valmaskmin+1; // FIXME: this is an abstraction breakage
+ private static final long mask = ~(-1L << DataLatch_WIDTH);
+ public static boolean isSmallEnoughToFit(long immediate) {
+ if ((immediate & ~mask) == 0) return true;
+ if ((immediate | mask) == -1L) return true;
+ return false;
+ }
/** get the bits describing this box's location on the DESTINATION HORN */
- protected abstract long getDestAddr(Destination box);
+ protected abstract long getDestAddr(Path box);
- /** get the bits describing this box's location on the INSTRUCTION HORN */
- protected abstract long getBoxInstAddr(Pump box);
+ /** decode a path, given the starting point and the bits that comprise it */
+ protected abstract Path getPathByAddr(Dock source, long dest);
- /** given an INSTRUCTION HORN address, retrieve the corresponding Pump object */
- protected abstract Pump getBoxByInstAddr(long dest);
-
- /** given a DESTINATION HORN address, retrieve the corresponding Pump object */
- protected abstract Destination getDestByAddr(long dest);
+ /** FIXME: this is a hack for now */
+ protected abstract Dock getUniversalSource();
/** read a machine-formatted instruction from a file (into a Java object) */
- public Instruction readInstruction(DataInputStream is) throws IOException {
+ public Instruction readInstruction(Dock dispatchFrom, DataInputStream is) throws IOException {
long inst = 0;
try {
inst = (inst << 8) | (is.readByte() & 0xff);
inst = (inst << 8) | (is.readByte() & 0xff);
inst = (inst << 8) | (is.readByte() & 0xff);
inst = (inst << 8) | (is.readByte() & 0xff);
- return readInstruction(inst);
+ return readInstruction(dispatchFrom, inst);
} catch (EOFException eof) {
return null;
}
}
- public Instruction readInstruction(long inst) {
- Pump name = getBoxByInstAddr(PUMP_NAME.getval(inst));
-
- 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));
-
- int predicate = 0;
- if (P_ALWAYS.get(inst)) predicate = Instruction.PredicatedInstruction.P_ALWAYS;
- if (P_A.get(inst)) predicate = Instruction.PredicatedInstruction.P_IF_A;
- if (P_B.get(inst)) predicate = Instruction.PredicatedInstruction.P_IF_B;
- if (P_Z.get(inst)) predicate = Instruction.PredicatedInstruction.P_IF_Z;
+ public Instruction readInstruction(Dock dispatchFrom, long inst) {
+ Dock dock = getPathByAddr(getUniversalSource(), DISPATCH_PATH.getval(inst)).getDestination().getDock();
+
+ if (TAIL.get(inst)) return new Tail(dock);
+
+ Predicate predicate = Default;
+ if (P_ALWAYS.get(inst)) predicate = IgnoreOLC;
+ if (P_OLC.get(inst)) predicate = Default;
+ if (P_A.get(inst)) predicate = FlagA;
+ if (P_B.get(inst)) predicate = FlagB;
+ if (P_C.get(inst)) predicate = FlagC;
+ if (P_NOT_A.get(inst)) predicate = NotFlagA;
+ if (P_NOT_B.get(inst)) predicate = NotFlagB;
+ if (P_NOT_C.get(inst)) predicate = NotFlagC;
+
+ boolean looping = !OS.get(inst);
+ if (SHIFT.get(inst)) return new Shift(dock, looping, predicate, new BitVector(dock.getShip().getFleet().getWordWidth()).set(SHIFT.getval(inst)));
+ if (SET_IMMEDIATE.get(inst)) {
+ boolean extend = SET_IMMEDIATE_EXTEND.getval(inst) != 0;
+ long immediate = SET_IMMEDIATE.getval(inst);
+ if (extend) immediate |= (-1L << DataLatch_WIDTH);
+ return new Set(dock, looping, predicate, SetDest.DataLatch, (immediate));
+ }
- boolean dl = false;
- if (DL.get(inst)) dl = true;
-
- if (LOOP_FROM_LITERAL.get(inst)) return new Counter(name, dl, predicate, (int)LOOP_FROM_LITERAL.getval(inst), LOOP_COUNTER);
- if (REPEAT_FROM_LITERAL.get(inst)) return new Counter(name, dl, predicate, (int)REPEAT_FROM_LITERAL.getval(inst), REPEAT_COUNTER);
- if (LOOP_FROM_DATA.get(inst)) return new Counter(name, dl, predicate, DATA_LATCH, LOOP_COUNTER);
- if (REPEAT_FROM_DATA.get(inst)) return new Counter(name, dl, predicate, DATA_LATCH, REPEAT_COUNTER);
- if (REPEAT_FROM_STANDING.get(inst)) return new Counter(name, dl, predicate, STANDING, REPEAT_COUNTER);
- if (TAKE_LOOP.get(inst)) return new Counter(name, dl, predicate, LOOP_COUNTER, DATA_LATCH);
-
- if (LITERAL_LO.get(inst)) return new Instruction.HalfLiteral(name, dl, predicate, LITERAL_LO.getval(inst), 0, false);
- if (LITERAL_HI.get(inst)) return new Instruction.HalfLiteral(name, dl, predicate, LITERAL_HI.getval(inst), 0, true);
- if (LITERAL.get(inst)) {
- long literal = LITERAL.getval(inst);
- if (LITERAL_LOW_ZERO.get(inst)) literal = TOP_HALF_LITERAL.setval(0, literal);
- else if (LITERAL_LOW_ONE.get(inst)) literal = BOT_HALF_ONE.set(TOP_HALF_LITERAL.setval(0, literal));
- else if (LITERAL_HIGH_ZERO.get(inst)) literal = BOT_HALF_LITERAL.setval(0, literal);
- else if (LITERAL_HIGH_ONE.get(inst)) literal = TOP_HALF_ONE.set(BOT_HALF_LITERAL.setval(0, literal));
- return new Instruction.Literal(name, dl, predicate, Mask.signExtend(literal, WIDTH_WORD));
- }
- if (FLAGS.get(inst)) return new Instruction.SetFlags(name, dl, predicate, (int)FLAGS_A.getval(inst), (int)FLAGS_B.getval(inst));
-
- if (!MOVE.get(inst)) throw new RuntimeException("unknown instruction: 0x" + Long.toString(inst, 16));
-
- 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 dataOutDest = PATH_DATA.get(inst);
- return new Instruction.Move(name,
- dl,
- predicate,
- dest,
- tokenIn,
- dataIn,
- latch,
- dataOutDest,
- dataOut,
- tokenOut,
- false,
- false);
+ if (SET_OLC_FROM_OLC_MINUS_ONE.get(inst))
+ return new Set(dock, looping, predicate, SetDest.OuterLoopCounter, SetSource.Decrement);
+ if (SET_OLC_FROM_IMMEDIATE.get(inst))
+ return new Set(dock, looping, predicate, SetDest.OuterLoopCounter, (SET_OLC_FROM_IMMEDIATE.getval(inst)));
+ if (SET_ILC_FROM_IMMEDIATE.get(inst))
+ return new Set(dock, looping, predicate, SetDest.InnerLoopCounter, (SET_ILC_FROM_IMMEDIATE.getval(inst)));
+ if (SET_OLC_FROM_DATA_LATCH.get(inst))
+ return new Set(dock, looping, predicate, SetDest.OuterLoopCounter, SetSource.DataLatch);
+ if (SET_ILC_FROM_DATA_LATCH.get(inst))
+ return new Set(dock, looping, predicate, SetDest.InnerLoopCounter, SetSource.DataLatch);
+ if (SET_ILC_FROM_INFINITY.get(inst))
+ return new Set(dock, looping, predicate, SetDest.InnerLoopCounter, SetSource.Infinity);
+ if (SET_FLAGS.get(inst)) {
+ long flag_a = SET_FLAGS_A.getval(inst);
+ long flag_b = SET_FLAGS_B.getval(inst);
+ FlagFunction ap = FlagFunction.ZERO;
+ FlagFunction bp = FlagFunction.ZERO;
+ if (SET_FLAGS_VALUE_A .get(flag_a)) ap = ap.add(FlagA );
+ if (SET_FLAGS_VALUE_NOT_A.get(flag_a)) ap = ap.add(NotFlagA );
+ if (SET_FLAGS_VALUE_B .get(flag_a)) ap = ap.add(FlagB );
+ if (SET_FLAGS_VALUE_NOT_B.get(flag_a)) ap = ap.add(NotFlagB );
+ if (SET_FLAGS_VALUE_C .get(flag_a)) ap = ap.add(FlagC );
+ if (SET_FLAGS_VALUE_NOT_C.get(flag_a)) ap = ap.add(NotFlagC );
+ if (SET_FLAGS_VALUE_A .get(flag_b)) bp = bp.add(FlagA );
+ if (SET_FLAGS_VALUE_NOT_A.get(flag_b)) bp = bp.add(NotFlagA );
+ if (SET_FLAGS_VALUE_B .get(flag_b)) bp = bp.add(FlagB );
+ if (SET_FLAGS_VALUE_NOT_B.get(flag_b)) bp = bp.add(NotFlagB );
+ if (SET_FLAGS_VALUE_C .get(flag_b)) bp = bp.add(FlagC );
+ if (SET_FLAGS_VALUE_NOT_C.get(flag_b)) bp = bp.add(NotFlagC );
+ return new Set(dock, looping, predicate, ap, bp);
+ }
+ if (SET_TAPL_FROM_IMMEDIATE.get(inst))
+ return new Set(dock, looping, predicate, SetDest.TAPL, getPathByAddr(dock, SET_TAPL_FROM_IMMEDIATE.getval(inst)));
+ if (MOVE.get(inst))
+ return new Move(dock,
+ looping,
+ predicate,
+ I.get(inst),
+ getPathByAddr(dock, PATH_IMMEDIATE.getval(inst)),
+ TI.get(inst),
+ DI.get(inst),
+ DC.get(inst),
+ PATH_DATA.get(inst),
+ DO.get(inst),
+ TO.get(inst)
+ );
+ throw new RuntimeException("unknown instruction: 0x" + Long.toString(inst, 16));
}
- public long writeInstruction(Instruction d) {
+ public long writeInstruction(Dock dispatchFrom, Instruction d) {
long instr = 0;
- if (d.pump != null)
- instr = PUMP_NAME.setval(instr, getBoxInstAddr(d.pump));
+ if (d.dock != null)
+ instr = DISPATCH_PATH.setval(instr, getDestAddr(getUniversalSource().getPath(d.dock.getInstructionDestination(),null)));
boolean dl = false;
- if (d instanceof Instruction.PredicatedInstruction) {
- Instruction.PredicatedInstruction pi = (Instruction.PredicatedInstruction)d;
- if (pi.dl) instr = DL.set(instr);
- switch(pi.predicate) {
- case Instruction.PredicatedInstruction.P_ALWAYS: instr = P_ALWAYS.set(instr); break;
- case Instruction.PredicatedInstruction.P_IF_A: instr = P_A.set(instr); break;
- case Instruction.PredicatedInstruction.P_IF_B: instr = P_B.set(instr); break;
- case Instruction.PredicatedInstruction.P_IF_Z: instr = P_Z.set(instr); break;
- }
- }
-
- if (d instanceof Instruction.CodeBagDescriptor) {
- Instruction.CodeBagDescriptor lc = (Instruction.CodeBagDescriptor)d;
- // MAJOR MAJOR FIXME: upper half here...
- d = new Instruction.HalfLiteral(lc.pump, dl, Instruction.PredicatedInstruction.P_ALWAYS,
- ((lc.offset << WIDTH_CODEBAG_SIZE)) | lc.size, 1, false);
+ Instruction pi = d;
+ if (!pi.looping) instr = OS.set(instr);
+ switch(pi.predicate) {
+ case IgnoreOLC: instr = P_ALWAYS.set(instr); break;
+ case Default: instr = P_OLC.set(instr); break;
+ case FlagA: instr = P_A.set(instr); break;
+ case FlagB: instr = P_B.set(instr); break;
+ case FlagC: instr = P_C.set(instr); break;
+ case NotFlagA: instr = P_NOT_A.set(instr); break;
+ case NotFlagB: instr = P_NOT_B.set(instr); break;
+ case NotFlagC: instr = P_NOT_C.set(instr); break;
}
- if (d instanceof Instruction.UnClog) {
- instr = UNCLOG.set(instr);
-
- } else if (d instanceof Instruction.Kill) {
- Instruction.Kill k = (Instruction.Kill)d;
- instr = KILL.set(instr);
- instr = KILL.setval(instr, k.count);
-
- } else if (d instanceof Instruction.Clog) {
- instr = CLOG.set(instr);
-
- } else if (d instanceof Instruction.Massacre) {
- instr = MASSACRE.set(instr);
-
- } else if (d instanceof Instruction.SetFlags) {
- Instruction.SetFlags sf = (Instruction.SetFlags)d;
- instr = FLAGS.set(instr);
- instr = FLAGS_A.setval(instr, sf.flag_a);
- instr = FLAGS_B.setval(instr, sf.flag_b);
-
- } else if (d instanceof Instruction.Literal) {
- long il = ((Instruction.Literal)d).literal;
- if (TOP_HALF_ONE.get(il)) instr = LITERAL_LO.setval(LITERAL_HIGH_ONE.set(instr), BOT_HALF_LITERAL.getval(il));
- else if (TOP_HALF_LITERAL.getval(il)==0) instr = LITERAL_LO.setval(LITERAL_HIGH_ZERO.set(instr), BOT_HALF_LITERAL.getval(il));
- else if (BOT_HALF_ONE.get(il)) instr = LITERAL_HI.setval(LITERAL_LOW_ONE.set(instr), TOP_HALF_LITERAL.getval(il));
- else if (BOT_HALF_LITERAL.getval(il)==0) instr = LITERAL_HI.setval(LITERAL_LOW_ZERO.set(instr), TOP_HALF_LITERAL.getval(il));
- else throw new RuntimeException("literal cannot be encoded using a single instruction");
-
- } else if (d instanceof Instruction.HalfLiteral) {
- Instruction.HalfLiteral inst = (Instruction.HalfLiteral)d;
- if (inst.pump != null) {
- 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);
+ if (d instanceof Tail) {
+ instr = TAIL.set(instr);
+
+ } else if (d instanceof Shift) {
+ Shift shift = (Shift)d;
+ instr = SHIFT.set(instr);
+ instr = SHIFT.setval(instr, shift.immediate);
+
+ } else if (d instanceof Set) {
+ Set s = (Set)d;
+ switch(s.dest) {
+ case InnerLoopCounter:
+ switch(s.source) {
+ case DataLatch:
+ instr = SET_ILC_FROM_DATA_LATCH.set(instr);
+ break;
+ case Immediate:
+ instr = SET_ILC_FROM_IMMEDIATE.setval(SET_ILC_FROM_IMMEDIATE.set(instr), s.immediate);
+ break;
+ case Infinity:
+ instr = SET_ILC_FROM_INFINITY.set(instr);
+ break;
+ }
+ break;
+ case OuterLoopCounter:
+ switch(s.source) {
+ case Decrement:
+ instr = SET_OLC_FROM_OLC_MINUS_ONE.set(instr);
+ break;
+ case DataLatch:
+ instr = SET_OLC_FROM_DATA_LATCH.set(instr);
+ break;
+ case Immediate:
+ instr = SET_OLC_FROM_IMMEDIATE.setval(SET_OLC_FROM_IMMEDIATE.set(instr), s.immediate);
+ break;
+ }
+ break;
+ case TAPL: {
+ instr = SET_TAPL_FROM_IMMEDIATE.set(instr);
+ instr = SET_TAPL_FROM_IMMEDIATE.setval(instr, getDestAddr(s.path));
+ break;
+ }
+ case Flags: {
+ instr = SET_FLAGS.set(instr);
+ instr = SET_FLAGS_A.setval(instr, flagFunctionToLong(s.newFlagA));
+ instr = SET_FLAGS_B.setval(instr, flagFunctionToLong(s.newFlagB));
+ break;
+ }
+ case DataLatch: {
+ instr = SET_IMMEDIATE.set(instr);
+ instr = SET_IMMEDIATE_EXTEND.setval(instr, s.immediate < 0 ? 1 : 0);
+ instr = SET_IMMEDIATE.setval(instr, s.immediate & ~(-1L << DataLatch_WIDTH));
+ break;
}
- } else {
- instr = inst.literal;
}
- } else if (d instanceof Instruction.DecrLoop) {
- instr = DL.set(instr);
-
- } 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 == 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();
-
- } else if (d instanceof Instruction.Move) {
- Instruction.Move inst = (Instruction.Move)d;
+ } else if (d instanceof Move) {
+ Move inst = (Move)d;
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.latchData) 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);
+ if (inst.interruptible) instr = I.set(instr);
+
+ if (inst.latchPath) instr = PATH_DATA.set(instr);
else {
- instr = PATH_LITERAL.set(instr);
- instr = PATH_LITERAL.setval(instr, inst.dest==null?0:getDestAddr(inst.dest));
+ instr = PATH_IMMEDIATE.set(instr);
+ instr = PATH_IMMEDIATE.setval(instr, inst.path==null?0:getDestAddr(inst.path));
}
} else {
- throw new RuntimeException("unrecognized instruction " + d);
+ throw new RuntimeException("unrecognized instruction " + d.getClass().getName());
}
return instr;
}
- public void writeInstruction(DataOutputStream os, Instruction d) throws IOException {
- long instr = writeInstruction(d);
+ public void writeInstruction(DataOutputStream os, Dock dispatchFrom, Instruction d) throws IOException {
+ long instr = writeInstruction(dispatchFrom, d);
for(int i=5; i>=0; i--)
- os.write(getIntField(i*8+7, i*8, instr));
- }
+ os.write(BitManipulations.getIntField(i*8+7, i*8, instr));
+ }
-}
\ No newline at end of file
+ private static long flagFunctionToLong(FlagFunction ff) {
+ long ret = 0;
+ for(Predicate p : ff)
+ switch(p) {
+ case FlagA : ret = SET_FLAGS_VALUE_A .set(ret); break;
+ case NotFlagA : ret = SET_FLAGS_VALUE_NOT_A.set(ret); break;
+ case FlagB : ret = SET_FLAGS_VALUE_B .set(ret); break;
+ case NotFlagB : ret = SET_FLAGS_VALUE_NOT_B.set(ret); break;
+ case FlagC : ret = SET_FLAGS_VALUE_C .set(ret); break;
+ case NotFlagC : ret = SET_FLAGS_VALUE_NOT_C.set(ret); break;
+ default: throw new RuntimeException();
+ }
+ return ret;
+ }
+}
import edu.berkeley.sbp.util.ANSI;
import edu.berkeley.fleet.api.*;
import static edu.berkeley.fleet.util.BitManipulations.*;
+import edu.berkeley.fleet.two.*;
import java.util.*;
/** this is a generic inbox which stores <32-bit items (tokens or data) */
-public class Inbox extends InstructionPump {
+public class Inbox extends InstructionDock {
public boolean dataReadyForShip() { return itemReadyForShip; }
public Packet removePacketForShip() { remove(); return register; }
/** if an ack token is pending, this is where it should be sent once the item is accepted */
private Packet bufferedAck = null;
- public boolean isInbox() { return true; }
- public boolean isOutbox() { return false; }
-
- public Inbox(InterpreterShip ship, String name) { super(ship, name, new String[] { "" }); }
- public Inbox(InterpreterShip ship, String name, String[] ports) { super(ship, name, ports); }
+ public Inbox(InterpreterShip ship, DockDescription dd) { super(ship, new String[] { "" }, dd); }
+ public Inbox(InterpreterShip ship, String[] ports, DockDescription dd) { super(ship, ports, dd); }
public void addDataFromFabric(Packet packet) { itemsFromFabric.add(packet); }
private void remove() {
// if no instruction waiting, do nothing
if (instruction_ == null) return false;
+ /*
if (instruction_ instanceof Instruction.Literal) {
register = new Packet(getInterpreter(), null, ((Instruction.Literal)instruction_).literal, null);
return true;
register = new Packet(getInterpreter(), null, val, null);
return true;
}
+ */
Instruction.Move instruction = (Instruction.Move)instruction_;
// check firing conditions
// consume inbound data+token
if (instruction.dataIn) {
- if (instruction.latch) {
+ if (instruction.latchData) {
register = itemsFromFabric.remove();
} else {
itemsFromFabric.remove();
// and make note of the fact that we need to send an ack (if requested)
if (instruction.tokenOut)
- bufferedAck = new Packet(getInterpreter(), this, 0, (InterpreterDestination)instruction.dest);
+ bufferedAck = new Packet(getInterpreter(), this, 0, (InterpreterDestination)(Object)instruction.path);
} else if (instruction.tokenOut) {
// if dataOut is not set, we can send the data immediately
- new Packet(getInterpreter(), this, 0, (InterpreterDestination)instruction.dest).send();
+ new Packet(getInterpreter(), this, 0, (InterpreterDestination)(Object)instruction.path).send();
}
return true;
}
package edu.berkeley.fleet.interpreter;
import edu.berkeley.sbp.util.ANSI;
+import edu.berkeley.fleet.two.*;
import edu.berkeley.fleet.api.*;
-import edu.berkeley.fleet.doc.*;
import edu.berkeley.fleet.api.Instruction;
+import static edu.berkeley.fleet.api.Predicate.*;
import java.util.*;
/** anything that has a source (instruction horn) address on the switch fabric */
-abstract class InstructionPump extends InterpreterPump {
+abstract class InstructionDock extends InterpreterDock {
- public int clogged = 0;
+ public int tailged = 0;
public boolean flag_a = false;
public boolean flag_b = false;
+ public boolean flag_c = false;
/** the currently executing instruction */
private Instruction executing = null;
public int loopCounter = 0;
private int repeatCounter = 1;
- InstructionPump(InterpreterShip ship, String name, String[] ports) {
- super(ship, name, ports);
+ InstructionDock(InterpreterShip ship, String[] ports, DockDescription bbd) {
+ super(ship, ports, bbd);
}
public void massacre() {
protected abstract long peekDataLatch();
protected final void service() {
- if (clogged > 0) return;
+ /*
+ if (tailged > 0) return;
if (executing==null && instructions.size() > 0) executing = instructions.remove();
if (executing==null) return;
- if (executing instanceof Instruction.Clog) {
- clogged++;
- executing = null;
- return;
- }
-
boolean enabled = true;
if (executing instanceof Instruction.PredicatedInstruction) {
Instruction.PredicatedInstruction ip = (Instruction.PredicatedInstruction)executing;
switch(ip.predicate) {
- case Instruction.PredicatedInstruction.P_ALWAYS: enabled = true; break;
- case Instruction.PredicatedInstruction.P_IF_A: enabled = flag_a; break;
- case Instruction.PredicatedInstruction.P_IF_B: enabled = flag_b; break;
- case Instruction.PredicatedInstruction.P_IF_Z: enabled = loopCounter==0; break;
+ case IgnoreOLC: enabled = true; break;
+ case Default: enabled = loopCounter!=0; break;
+ case FlagA: enabled = flag_a; break;
+ case FlagB: enabled = flag_b; break;
+ //case FlagC: enabled = ; break;
+ case NotFlagA: enabled = !flag_a; break;
+ case NotFlagB: enabled = !flag_b; break;
+ //case NotFlagC: enabled = loopCounter==0; break;
}
}
int oldLoopCounter = loopCounter;
if (enabled) {
- if (executing.isDL()) loopCounter = Math.max(0, loopCounter-1);
-
+ if (executing instanceof Instruction.Set.OLC.Decrement) 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(oldLoopCounter); /* FIXME: which is correct here? */
+ setDataLatch(oldLoopCounter); // FIXME: which is correct here?
} 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) {
repeatCounter = ic.source;
}
- } else if (executing instanceof Instruction.SetFlags) {
- Instruction.SetFlags sf = (Instruction.SetFlags)executing;
- boolean old_s = ((peekDataLatch() >> (getInterpreter().getWordSize()-1)) & 1) != 0;
- boolean old_z = oldLoopCounter == 0;
+ } else if (executing instanceof Instruction.Set.Flags) {
+ Instruction.Set.Flags sf = (Instruction.Set.Flags)executing;
+ boolean old_c = oldLoopCounter == 0;
boolean old_a = flag_a;
boolean old_b = flag_b;
flag_a =
(((sf.flag_a & sf.FLAG_NOT_A) != 0) ? !old_a : false) |
(((sf.flag_a & sf.FLAG_B) != 0) ? old_b : false) |
(((sf.flag_a & sf.FLAG_NOT_B) != 0) ? !old_b : false) |
- (((sf.flag_a & sf.FLAG_Z) != 0) ? old_z : false) |
- (((sf.flag_a & sf.FLAG_NOT_Z) != 0) ? !old_z : false) |
- (((sf.flag_a & sf.FLAG_S) != 0) ? old_s : false) |
- (((sf.flag_a & sf.FLAG_NOT_S) != 0) ? !old_s : false);
+ (((sf.flag_a & sf.FLAG_C) != 0) ? old_c : false) |
+ (((sf.flag_a & sf.FLAG_NOT_C) != 0) ? !old_c : false);
flag_b =
(((sf.flag_b & sf.FLAG_A) != 0) ? old_a : false) |
(((sf.flag_b & sf.FLAG_NOT_A) != 0) ? !old_a : false) |
(((sf.flag_b & sf.FLAG_B) != 0) ? old_b : false) |
(((sf.flag_b & sf.FLAG_NOT_B) != 0) ? !old_b : false) |
- (((sf.flag_b & sf.FLAG_Z) != 0) ? old_z : false) |
- (((sf.flag_b & sf.FLAG_NOT_Z) != 0) ? !old_z : false) |
- (((sf.flag_b & sf.FLAG_S) != 0) ? old_s : false) |
- (((sf.flag_b & sf.FLAG_NOT_S) != 0) ? !old_s : false);
- } else if (executing instanceof Instruction.DecrLoop) {
+ (((sf.flag_b & sf.FLAG_C) != 0) ? old_c : false) |
+ (((sf.flag_b & sf.FLAG_NOT_C) != 0) ? !old_c : false);
+ } else if (executing instanceof Instruction.Set.OLC.Decrement) {
} else {
if (!service(executing)) return;
}
}
if (executing==null) return;
- if (executing.isRepeating() && repeatCounter > 1) {
+ if ((executing instanceof Instruction.Move) && repeatCounter > 1) {
repeatCounter--;
- } else if (executing.isRepeating() && repeatCounter == -1) {
+ } else if ((executing instanceof Instruction.Move) && repeatCounter == -1) {
// repeat
- } else if (executing.isLooping() && oldLoopCounter > 0) {
+ } else if ((executing instanceof Instruction.PredicatedInstruction && ((Instruction.PredicatedInstruction)executing).looping) && oldLoopCounter > 0) {
addInstruction(executing);
executing = null;
} else {
executing = null;
}
+ */
}
+
}
import java.lang.reflect.*;
import edu.berkeley.fleet.*;
import edu.berkeley.sbp.util.ANSI;
-import edu.berkeley.fleet.doc.*;
import edu.berkeley.fleet.api.*;
import edu.berkeley.fleet.ies44.*;
+import edu.berkeley.fleet.assembler.*;
+import edu.berkeley.fleet.two.*;
+import edu.berkeley.fleet.util.*;
+
+public class Interpreter extends Fleet implements Parser.FleetWithDynamicShips {
+
+ public Ship getShip(String type, int ordinal) {
+ for(Ship s : this)
+ if (s.getType().equals(type))
+ if (ordinal-- < 0)
+ return s;
+ return null;
+ }
-public class Interpreter extends Fleet implements Fleet.WithDynamicShips {
-
+ public int getWordWidth() { return 37; }
/** some "halt ship" can turn this on to stop the interpreter */
private HashMap<String,InterpreterShip> ships = new HashMap<String,InterpreterShip>();
private BlockingQueue<Long> debugStream = new LinkedBlockingQueue<Long>();
public FleetProcess run(final byte[] instructions) {
try {
final FleetProcess fp = new FleetProcess() {
+ public void dispatchInstruction(Instruction i) { throw new RuntimeException(); }
public void invokeInstruction(Instruction i) { throw new RuntimeException("not supported"); }
- public long readWord() {
+ public Dock getDebugInputDock() { return null; }
+ public BitVector readWord() {
+ /*
try {
return debugStream.take();
} catch (Exception e) {
throw new RuntimeException(e);
- } }
+ }*/
+ throw new RuntimeException();
+ }
protected void _terminate() {
// FIXME: hack
ships = new HashMap<String,InterpreterShip>();
iscratch = (InterpreterShip)ship;
break;
}
- if (iscratch==null)
+ if (iscratch==null) {
+ BufferedReader br =
+ new BufferedReader(new InputStreamReader(new FileInputStream("ships/Memory.ship")));
+ ShipDescription sd = new ShipDescription("Memory", br);
iscratch = (InterpreterShip)Class.forName("edu.berkeley.fleet.interpreter.Memory")
- .getConstructor(new Class[] { Interpreter.class, String.class })
- .newInstance(new Object[] { Interpreter.this, "memory" });
+ .getConstructor(new Class[] { Interpreter.class, String.class, ShipDescription.class })
+ .newInstance(new Object[] { Interpreter.this, "memory", sd });
+ }
iscratch
.getClass()
.getMethod("boot", new Class[] { byte[].class })
public void dispatch(Instruction i, long address) {
Log.dispatch(i);
- if (i instanceof Instruction.CodeBagDescriptor) {
- Instruction.CodeBagDescriptor cbd = (Instruction.CodeBagDescriptor)i;
- long absolute_cbd = ((cbd.offset+address) << 6) | cbd.size;
- throw new RuntimeException();
- //new Packet(this, null, (int)absolute_cbd, (InterpreterDestination)cbd.pump).send();
-
- } else if (i instanceof Instruction.UnClog) {
- Instruction.UnClog ic = (Instruction.UnClog)i;
- ((InstructionPump)(ic.pump)).clogged--;
-
- } else if (i instanceof Instruction.Kill) {
- InterpreterPump pump = (InterpreterPump)(((Instruction.Kill)i).pump);
- ((InstructionPump)pump).kill();
-
- } else if (i instanceof Instruction.Massacre) {
- InterpreterPump pump = (InterpreterPump)(((Instruction.Massacre)i).pump);
- ((InstructionPump)pump).massacre();
+
+ if (i instanceof Instruction.Tail) {
+ Instruction.Tail ic = (Instruction.Tail)i;
+ ((InstructionDock)(ic.dock)).tailged--;
} else {
- InterpreterPump sourcePump = (InterpreterPump)(((Instruction)i).pump);
- ((InstructionPump)sourcePump).addInstruction(((Instruction)i));
+ InterpreterDock sourceDock = (InterpreterDock)(((Instruction)i).dock);
+ ((InstructionDock)sourceDock).addInstruction(((Instruction)i));
}
}
public Ship createShip(String shipType, String shipname) {
try {
Class c = Class.forName("edu.berkeley.fleet.interpreter."+shipType);
- Constructor con = c.getConstructor(new Class[] { Interpreter.class, String.class });
- InterpreterShip ret = (InterpreterShip)con.newInstance(new Object[] { this, shipname });
+ Constructor con = c.getConstructor(new Class[] { Interpreter.class, String.class, ShipDescription.class });
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("ships/"+shipType+".ship")));
- ShipDescription sd = new ShipDescription(shipname, br);
- ret.setShipDescription(sd);
+ ShipDescription sd = new ShipDescription(shipType, br);
+ InterpreterShip ret = (InterpreterShip)con.newInstance(new Object[] { this, shipname, sd });
ships.put(shipname, ret);
return ret;
} catch (Exception e) {
+ e.printStackTrace();
return null;
}
}
// Instruction Encoding /////////////////////////////////////////////////////////////////////////
public final InterpreterInstructionEncoder iie = new InterpreterInstructionEncoder();
- public Instruction readInstruction(DataInputStream is) throws IOException { return iie.readInstruction(is); }
- public Instruction readInstruction(long instr) { return iie.readInstruction(instr); }
- public long writeInstruction(Instruction d) { return writeInstruction(d); }
- public void writeInstruction(DataOutputStream os, Instruction d) throws IOException { iie.writeInstruction(os, d); }
+ public Instruction readInstruction(DataInputStream is, Dock dispatchFrom) throws IOException { return iie.readInstruction(dispatchFrom, is); }
+ public Instruction readInstruction(Dock dispatchFrom, long instr) { return iie.readInstruction(dispatchFrom, instr); }
+ public long writeInstruction(Dock dispatchFrom, Instruction d) { return writeInstruction(dispatchFrom, d); }
+ public void writeInstruction(DataOutputStream os, Dock dispatchFrom, Instruction d) throws IOException { iie.writeInstruction(os, dispatchFrom, d); }
+ public Dock getUniversalSource() { return null; }
public class InterpreterInstructionEncoder extends InstructionEncoder {
- public long getDestAddr(Destination box) { return ((InterpreterDestination)box).getDestAddr(); }
- public long getBoxInstAddr(Pump box) { return ((InterpreterPump)box).getDestAddr(); }
+ public Dock getUniversalSource() { return null; }
+ public long getDestAddr(Path path) { throw new RuntimeException(); }
+ public long getBoxInstAddr(Dock box) { return ((InterpreterDock)box).getDestAddr(); }
+ public Path getPathByAddr(Dock source, long dest) { throw new RuntimeException(); }
public Destination getDestByAddr(long dest) {
+ /*
for(Ship ship : Interpreter.this)
- for(Pump bb : ship.getPumps())
- for(Destination d : bb.getDestinations())
- if (getDestAddr(d)==dest)
- return d;
+ for(Dock bb : ship)
+ if (getDestAddr(bb.getDataDestination())==dest)
+ return bb.getDataDestination();
+ */
return null;
}
- public Pump getBoxByInstAddr(long dest) {
+ public Dock getBoxByInstAddr(long dest) {
for(Ship ship : Interpreter.this)
- for(Pump bb : ship.getPumps())
+ for(Dock bb : ship)
if (getBoxInstAddr(bb) == dest)
return bb;
return null;
pw.println("package edu.berkeley.fleet.interpreter;");
pw.println("import edu.berkeley.sbp.util.ANSI;");
pw.println("import edu.berkeley.fleet.api.*;");
+ pw.println("import edu.berkeley.fleet.two.*;");
pw.println("import edu.berkeley.fleet.*;");
pw.println("import java.util.*;");
pw.println("import java.io.*;");
pw.println("");
pw.println("public class "+filename+" extends InterpreterShip {");
pw.println("");
- for(PumpDescription b : sd) {
+ for(DockDescription b : sd) {
String name = b.getName();
pw.print(" ");
- if ( b.isInbox()) pw.print("Inbox");
- if (!b.isInbox()) pw.print("Outbox");
+ if ( b.isInputDock()) pw.print("Inbox");
+ if (!b.isInputDock()) pw.print("Outbox");
pw.print(" box_");
pw.print(name);
pw.print(" = new ");
- if ( b.isInbox()) pw.print("Inbox");
- if (!b.isInbox()) pw.print("Outbox");
- pw.print("(this, \""+name+"\", new String[] { ");
+ if ( b.isInputDock()) pw.print("Inbox");
+ if (!b.isInputDock()) pw.print("Outbox");
+ pw.print("(this, new String[] { ");
boolean first = true;
- for(String destination : b) {
- if (!first) pw.print(", ");
- first = false;
- pw.print("\""+destination+"\"");
- }
- pw.println("});");
+ pw.print("\"\"");
+ pw.println("}, shipDescription.getDockDescription(\""+name+"\"));");
}
pw.println("");
- pw.println(" public "+filename+"(Interpreter fleet, String name) {");
- pw.println(" super(fleet, name, \""+filename+"\");");
- for(PumpDescription b : sd)
- pw.println(" addPump(\""+b.getName()+"\", box_"+b.getName()+");");
+ pw.println(" public "+filename+"(Interpreter fleet, String name, ShipDescription sd) {");
+ pw.println(" super(fleet, name, sd);");
+ for(DockDescription b : sd)
+ pw.println(" addDock(\""+b.getName()+"\", box_"+b.getName()+");");
pw.println(" }");
pw.println("");
pw.println(sd.getSection("fleeterpreter"));
import java.util.*;
abstract class InterpreterDestination extends Destination {
+ public InterpreterDestination(InterpreterDock d, boolean isInstructionDestination) { super(d); }
public abstract long getDestAddr();
public abstract void addDataFromFabric(Packet packet);
public abstract String getDestinationName();
-}
\ No newline at end of file
+}
package edu.berkeley.fleet.interpreter;
-import edu.berkeley.fleet.doc.*;
import edu.berkeley.fleet.api.*;
-import edu.berkeley.fleet.api.Pump;
+import edu.berkeley.fleet.api.Dock;
+import edu.berkeley.fleet.two.*;
import java.util.*;
+
/** anything that has a destination address on the switch fabric */
-public abstract class InterpreterPump extends Pump {
+public abstract class InterpreterDock extends FleetTwoDock {
- private final String name;
private final InterpreterShip ship;
private final Destination[] ports;
private final int addr = max_addr++;
- private PumpDescription bbd;
-
- public void setDescription(PumpDescription bbd) {
- this.bbd = bbd;
- }
- public long resolveLiteral(String literal) {
- return bbd.resolveLiteral(literal);
- }
- public InterpreterPump(InterpreterShip ship, String name, String[] ports) {
+ public InterpreterDock(InterpreterShip ship, String[] ports, DockDescription bbd) {
+ super(ship, bbd);
this.ship = ship;
- this.name = name;
this.ports = new Destination[ports.length];
for(int i=0; i<ports.length; i++)
this.ports[i] =
- new InterpreterPumpDestination(ports[i]);
+ new InterpreterDockDestination(ports[i], this, false);
+ }
+
+ public Path getPath(Destination d, BitVector signal) {
+ throw new RuntimeException();
}
public Iterable<Destination> getDestinations() {
return ret;
}
+ public Destination getInstructionDestination() {
+ return ports[0];
+ }
+ public Destination getDataDestination() {
+ return ports[0];
+ }
+
+
/** adds the included datum to the port from the switch fabric side */
public abstract void addDataFromFabric(Packet packet);
public Ship getShip() { return ship; }
public Fleet getFleet() { return getShip().getFleet(); }
- public String toString() { return ship+"."+name; }
- public String getName() { return name; }
- public int getInstructionFifoLength() { return 4; }
+ public String toString() { return ship+"."+getName(); }
+ public int getInstructionFifoSize() { return 4; }
Interpreter getInterpreter() { return ((InterpreterShip)getShip()).getInterpreter(); }
public long getDestAddr() { return addr; }
private static int max_addr;
-
- private class InterpreterPumpDestination extends InterpreterDestination {
+ private class InterpreterDockDestination extends InterpreterDestination {
public String name;
public long addr = max_addr++;
- public InterpreterPumpDestination(String name) { this.name = name; }
+ public InterpreterDockDestination(String name, InterpreterDock id, boolean isInstructionDestination) {
+ super(id, isInstructionDestination);
+ this.name = name;
+ }
public String getDestinationName() { return name; }
- public Ship getShip() { return InterpreterPump.this.getShip(); }
- public void addDataFromFabric(Packet packet) { InterpreterPump.this.addDataFromFabric(packet); }
+ public Ship getShip() { return InterpreterDock.this.getShip(); }
+ public void addDataFromFabric(Packet packet) { InterpreterDock.this.addDataFromFabric(packet); }
public String toString() { return getShip()+"."+getName(); }
public long getDestAddr() { return addr; }
}
package edu.berkeley.fleet.interpreter;
import edu.berkeley.fleet.api.*;
-import edu.berkeley.fleet.doc.*;
+import edu.berkeley.fleet.two.*;
import java.util.*;
import java.io.*;
/** a ship, which belongs to a fleet and which may have many ports */
-abstract class InterpreterShip extends Ship {
+abstract class InterpreterShip extends FleetTwoShip {
/** You should instantiate a bunch of Inboxes and Outboxes in your constructor */
- public InterpreterShip(Interpreter fleet, String name, String type) {
- this.fleet = fleet;
- this.type = type;
+ public InterpreterShip(Interpreter fleet, String name, ShipDescription sd) {
+ super(fleet, sd);
}
- private Interpreter fleet;
- private String type;
- private HashMap<String,InterpreterPump> ports = new HashMap<String,InterpreterPump>();
+ private HashMap<String,InterpreterDock> ports = new HashMap<String,InterpreterDock>();
- public Iterable<Pump> getPumps() { return (Iterable<Pump>)(Object)ports.values(); }
- public String getType() { return type; }
- public Fleet getFleet() { return fleet; }
- public Interpreter getInterpreter() { return fleet; }
-
- public void setShipDescription(ShipDescription sd) {
- for(InterpreterPump ibb : ports.values()) {
- for(PumpDescription bbd : sd) {
- if (bbd.getName().equals(ibb.getName()))
- ibb.setDescription(bbd);
- }
- }
- }
+ public Iterator<Dock> iterator() { return (Iterator<Dock>)(Object)ports.values().iterator(); }
+ public Interpreter getInterpreter() { return (Interpreter)getFleet(); }
/**
* Override this method, check inboxes for the data you need, and
public abstract void service();
public final void _service() {
- for(InterpreterPump p : ports.values()) p.service();
+ for(InterpreterDock p : ports.values()) p.service();
service();
}
- protected void addPump(String name, InterpreterPump port) {
+ protected void addDock(String name, InterpreterDock port) {
ports.put(name, port);
}
public void shutdown() {
- for(InterpreterPump p : ports.values())
+ for(InterpreterDock p : ports.values())
p.shutdown();
}
}
println(ANSI.green("dispatch: " + indent(d+"", " ")));
}
- public static void data(String data, Pump source, Destination dest) {
+ public static void data(String data, Dock source, Destination dest) {
println((" data: ") + indent(ANSI.purple(data) +
(source==null ? "" :
(" : " + source))+(" -> "+ANSI.purple(""+dest)), " "));
}
- public static void token(Pump source, Destination dest) {
+ public static void token(Dock source, Destination dest) {
println(ANSI.purple(" token: ") + (source + " -> " + ANSI.purple(dest+"")));
}
import edu.berkeley.sbp.util.*;
import edu.berkeley.fleet.util.*;
import static edu.berkeley.fleet.util.BitManipulations.*;
+import edu.berkeley.fleet.two.*;
import edu.berkeley.fleet.api.Instruction;
-public class Outbox extends InstructionPump {
+public class Outbox extends InstructionDock {
/** are we ready to accept another item from the ship? */
private boolean readyForDataFromShip = false;
/** the latched value */
private long register;
- public boolean isInbox() { return false; }
- public boolean isOutbox() { return true; }
- public Outbox(InterpreterShip ship, String name) { this(ship, name, new String[] { "" }); }
- public Outbox(InterpreterShip ship, String name, String[] ports) { super(ship, name, ports); }
+ public Outbox(InterpreterShip ship, DockDescription dd) { this(ship, new String[] { "" }, dd); }
+ public Outbox(InterpreterShip ship, String[] ports, DockDescription dd) { super(ship, ports, dd); }
protected void setDataLatch(long value) { register = value; }
protected long peekDataLatch() { return register; }
protected final boolean service(Instruction instruction_) {
+ /*
if (instruction_ instanceof Instruction.Literal) {
register = ((Instruction.Literal)instruction_).literal;
return true;
: setField(18, 0, ll.literal, register);
return true;
}
+ */
Instruction.Move instruction = (Instruction.Move)instruction_;
// if no instruction waiting, do nothing
// consume item
if (instruction.dataIn) {
haveDataFromShip = false;
- if (instruction.latch)
+ if (instruction.latchData)
register = itemPresentedByShip;
}
if (instruction.dataOut) {
// if item to be transmitted, send it
- InterpreterDestination dest = (InterpreterDestination)instruction.dest;
- if (instruction.dataOutDest) {
+ InterpreterDestination dest = (InterpreterDestination)(Object)instruction.path;
+ if (instruction.latchPath) {
// FIXME: still not supported
- long bits = InstructionEncoder.PUMP_NAME.getval(register);
- getInterpreter().dispatch(((Interpreter)getInterpreter()).iie.readInstruction(register), bits);
+ long bits = InstructionEncoder.DISPATCH_PATH.getval(register);
+ getInterpreter().dispatch(((Interpreter)getInterpreter()).iie.readInstruction(null, register), bits);
/*
dest = (InterpreterDestination)(((Interpreter)getInterpreter()).iie.getDestByAddr(bits));
if (dest == null) {
if (pump != null) {
- Pump pump = ((Interpreter)getInterpreter()).iie.getDestByInstAddr(bits);
+ Dock pump = ((Interpreter)getInterpreter()).iie.getDestByInstAddr(bits);
}
}
*/
} else if (instruction.tokenOut) {
// if no item was sent, we might still send an ack
- new Packet(getInterpreter(), this, 0, (InterpreterDestination)instruction.dest).send();
+ new Packet(getInterpreter(), this, 0, (InterpreterDestination)(Object)instruction.path).send();
}
return true;
import java.lang.reflect.*;
import edu.berkeley.fleet.*;
import edu.berkeley.sbp.util.ANSI;
-import edu.berkeley.fleet.doc.*;
import edu.berkeley.fleet.api.*;
import edu.berkeley.fleet.ies44.*;
long value;
InterpreterDestination destination;
- public Packet(Interpreter interpreter, InterpreterPump source, long value, InterpreterDestination destination) {
+ public Packet(Interpreter interpreter, InterpreterDock source, long value, InterpreterDestination destination) {
Log.data(value+"", source, (Destination)destination);
this.interpreter = interpreter;
this.value = value;
destination.addDataFromFabric(this);
}
-}
\ No newline at end of file
+}
--- /dev/null
+package edu.berkeley.fleet;
+
+// interesting primitive: an "atomic"
+// take-from-fred-and-deliver-to-mary transition; you can give it
+// predecessors and successors.
+// -- hitch: this artificially causes fred's successor to wait until
+// mary has gotten the data item
+
+
+// Literal gets folded into anything involving a UsesData
+// Repeat-literal-count appears to the programmer just as repeat with a separate literal
+// FEATURE: apply tachio analysis to ensure kills never get stuck
+// FEATURE: ability to save the MSB flag for later use
+public class IR {
+ /*
+ public interface Nodes extends Iterable<Node> {
+ }
+
+ public class NodesImpl extends Nodes {
+ public NodesImpl(Node[] ns) { } // FIXME
+ public NodesImpl(Node n1, Node n2) { this(new Node[] { n1, n2 }); }
+ public NodesImpl() { this(new Node[0]); }
+ //public Iterator<Node> iterator() { return new SingletonIterator(this); }
+ }
+
+ public abstract class Node extends Nodes {
+ public abstract Nodes preds();
+ public abstract Nodes succs();
+ public Iterator<Node> iterator() { return new SingletonIterator(this); }
+ }
+
+ public class Join extends Node {
+ public Node succ;
+ public Nodes preds;
+ public Nodes preds() { return preds; }
+ public Nodes succs() { return succ; }
+ }
+ public class Fork extends Node {
+ public Node pred;
+ public Nodes succs;
+ public Nodes preds() { return pred; }
+ public Nodes succs() { return succs; }
+ }
+
+ public abstract class Linear extends Node {
+ public Node pred;
+ public Node succ;
+ public Nodes preds() { return pred; }
+ public Nodes succs() { return succ; }
+ }
+
+ // Actual Instructions //////////////////////////////////////////////////////////////////////////////
+
+ public class Repeat extends Linear {
+ public Node bodyFirst;
+ public Node bodyLast;
+ public Nodes preds() { return new Nodes(pred, bodyLast); }
+ public Nodes succs() { return new Nodes(succ, bodyFirst); }
+ }
+
+ public class RepeatCount extends Repeat implements UsesData {
+ }
+
+ // if nonnegative then...else...
+ public class IfThenElse extends Linear implements UsesData {
+ public Node thenFirst;
+ public Node thenLast;
+ public Node elseFirst;
+ public Node elseLast;
+ public Join impliedJoin;
+ }
+
+ public class Break extends Linear { }
+
+ public class Deliver extends Linear implements UsesData { }
+ public class Recv extends Linear implements UsesData { } // is marked killable if any torpedo "points at" it
+ public class Collect extends Linear { }
+ public class Send extends Linear {
+ public Ship dest; // if null, then this is a "dispatch"
+ public boolean token;
+ public boolean torpedo;
+ }
+ */
+}
--- /dev/null
+package edu.berkeley.fleet.two;
+import edu.berkeley.fleet.api.*;
+import java.io.*;
+import java.util.*;
+
+/** NOT YET FINALIZED: A description of a dock on a ship */
+public class DockDescription {
+
+ private final ShipDescription ship;
+ private final String name;
+ private final boolean inbox;
+ private final boolean left;
+ private final HashMap<String,ShipDescription.Constant> constants = new HashMap<String,ShipDescription.Constant>();
+
+ DockDescription(ShipDescription ship, String name, boolean left, boolean inbox) {
+ this.left = left;
+ this.ship = ship;
+ this.name = name;
+ this.inbox = inbox;
+ }
+
+ public String getName() { return name; }
+ public boolean isInputDock() { return inbox; }
+ public boolean isOutputDock() { return !inbox; }
+
+ /** Indicates if this dock should be drawn on the "left hand side" of the ship for visual purposes */
+ boolean isLeft() { return left; }
+
+ /** Searches the dock-specific constants first, then ship-wide constants */
+ public ShipDescription.Constant getConstant(String name) {
+ ShipDescription.Constant ret = constants.get(name);
+ if (ret == null) ret = ship.getConstant(name);
+ return ret;
+ }
+
+ void addConstant(String s, ShipDescription.Constant c) { constants.put(s, c); }
+}
--- /dev/null
+package edu.berkeley.fleet.two;
+import edu.berkeley.fleet.api.*;
+import java.util.*;
+
+/** A dock on a ship */
+public abstract class FleetTwoDock extends Dock {
+
+ private final DockDescription dockDescription;
+
+ public FleetTwoDock(Ship ship, DockDescription dockDescription) {
+ super(ship);
+ this.dockDescription = dockDescription;
+ }
+
+ public String getName() { return dockDescription.getName(); }
+
+ public ShipDescription.Constant getConstant(String s) { return dockDescription.getConstant(s); }
+
+ public boolean isInputDock() { return dockDescription.isInputDock(); }
+
+ public boolean isOutputDock() { return !dockDescription.isInputDock(); }
+
+
+}
--- /dev/null
+package edu.berkeley.fleet.two;
+import edu.berkeley.fleet.api.*;
+import java.util.*;
+
+/** A ship in a Fleet; each ship consists of a collection of <tt>Dock</tt>s */
+public abstract class FleetTwoShip extends Ship {
+
+ protected final ShipDescription shipDescription;
+
+ public FleetTwoShip(Fleet fleet, ShipDescription shipDescription) {
+ super(fleet);
+ this.shipDescription = shipDescription;
+ }
+
+ /** returns the type of the ship ("Fetch", "ALU", etc) */
+ public String getType() { return shipDescription.getName(); }
+
+ public Dock getDock(String s) {
+ for(Dock b : this)
+ if (b.getName().equals(s))
+ return b;
+ throw new RuntimeException("unknown port \""+getType()+"."+s+"\"");
+ }
+
+ public int getOrdinal() {
+ int ord = 0;
+ for(Ship s : getFleet()) {
+ if (s==this) return ord;
+ if (s.getType() != null && s.getType().equals(getType())) ord++;
+ }
+ throw new RuntimeException("inconsistency: Ship does not belong to its own Fleet!");
+ }
+}
--- /dev/null
+package edu.berkeley.fleet.two;
+import edu.berkeley.fleet.api.*;
+import java.io.*;
+import java.util.*;
+
+/** NOT YET FINALIZED: A description (specification) of a ship */
+public class ShipDescription implements Iterable<DockDescription> {
+
+ private String name;
+ private LinkedHashMap<String,DockDescription> docks = new LinkedHashMap<String,DockDescription>();
+ private HashMap<String,String> sections = new HashMap<String,String>();
+ private HashMap<String,Constant> constants = new HashMap<String,Constant>();
+
+ public String getName() { return name; }
+ public String getSection(String sectionName) { return sections.get(sectionName); }
+ public DockDescription getDockDescription(String name) { return docks.get(name); }
+ public Iterator<DockDescription> iterator() { return docks.values().iterator(); }
+
+ public ShipDescription(String name, BufferedReader r) throws IOException {
+ this.name = name;
+ String sectionName = null;
+ StringBuffer sb = new StringBuffer();
+ while(true) {
+ String s = r.readLine();
+ if (s==null || s.startsWith("==")) {
+ if (sectionName != null) sections.put(sectionName, sb.toString());
+ if (s==null) break;
+ sb = new StringBuffer();
+ sectionName = s.trim();
+ while(sectionName.startsWith("="))
+ sectionName = sectionName.substring(1);
+ while(sectionName.endsWith("="))
+ sectionName = sectionName.substring(0, sectionName.length()-1);
+ sectionName = sectionName.trim().toLowerCase();
+ continue;
+ }
+ sb.append(s+"\n");
+ }
+ for(String s : sections.keySet())
+ processSection(s);
+ }
+
+ public Constant getConstant(String name) {
+ return constants.get(name);
+ }
+
+ private void processSection(String section) throws IOException {
+ if (section.equals("")) {
+ BufferedReader br = new BufferedReader(new StringReader(sections.get(section)));
+ for(String s = br.readLine(); s != null; s = br.readLine()) {
+ if (s.trim().length()==0) continue;
+ String key = s.substring(0, s.indexOf(':')).trim();
+ String val = s.substring(s.indexOf(':')+1).trim();
+ if (key.toLowerCase().equals("ship"))
+ name = val.trim();
+ }
+ } else if (section.equals("constants")) {
+ BufferedReader br = new BufferedReader(new StringReader(sections.get(section)));
+ for(String s = br.readLine(); s != null; s = br.readLine()) {
+ if (s.indexOf(':')==-1) continue;
+ String key = s.substring(0, s.indexOf(':')).trim();
+ if (key.startsWith("constant")) {
+ String constname = key.substring("constant".length()+1).trim();
+ String val = s.substring(s.indexOf(':')+1).trim();
+ constants.put(constname, new Constant(val));
+ }
+ }
+ } else if (section.equals("ports")) {
+ BufferedReader br = new BufferedReader(new StringReader(sections.get(section)));
+ boolean rightSide = false;
+ DockDescription p = null;
+ for(String s = br.readLine(); s != null; s = br.readLine()) {
+ if (s.trim().length()==0) { rightSide = true; continue; }
+
+ String key = s.substring(0, s.indexOf(':')).trim();
+ boolean inbox = false;
+ key = key.replaceAll(" +", " ");
+ if (key.equals("data in")) { inbox = true; }
+ else if (key.equals("data out")) { inbox = false; }
+ else if (key.equals("in")) { inbox = true; }
+ else if (key.equals("out")) { inbox = false; }
+ else if (key.startsWith("constant")) {
+ String constname = key.substring("constant".length()+1).trim();
+ String val = s.substring(s.indexOf(':')+1).trim();
+ p.addConstant(constname, new Constant(val));
+ continue;
+ } else if (key.startsWith("shortcut to")) {
+ continue;
+ }
+ else throw new RuntimeException("unknown port type: \""+key+"\"");
+
+ p = null;
+ String val = s.substring(s.indexOf(':')+1).trim();
+ String boxname = val.indexOf('.') != -1 ? val.substring(0, val.indexOf('.')) : val;
+ String dest = val.indexOf('.') != -1 ? val.substring(val.indexOf('.')+1) : "";
+ p = docks.get(boxname);
+ if (p==null) {
+ p = new DockDescription(this, boxname, !rightSide, inbox);
+ docks.put(boxname, p);
+ }
+ }
+ }
+ }
+
+ public void printTeX(PrintWriter pw) throws Exception {
+ ShipDescription sd = this;
+ pw.println("\\pagebreak");
+ pw.println("\\section*{The {\\tt "+sd.getName()+"} Ship}");
+ pw.println("\\addcontentsline{toc}{subsection}{"+sd.getName()+"}");
+ String tex = sd.getSection("tex");
+ /*
+ for(DockDescription bbd : sd) {
+ pw.println("{\\bf "+(bbd.isInputDock() ? "Input: " : "Output: ")+"{\\tt "+bbd.getName()+"}}\n\n");
+ }
+ */
+ int boxGap = 5;
+ int boxHeight = 25;
+ int boxWidth = 75;
+
+ int leftSize = 0;
+ int rightSize = 0;
+ for(DockDescription bbd : sd)
+ if (bbd.isLeft()) leftSize += (boxHeight+boxGap);
+ else rightSize += (boxHeight+boxGap);
+
+ int totalHeight = Math.max(leftSize, rightSize);
+ int shipWidth = (int)(boxWidth * 1.5);
+ int totalWidth = boxGap*2 + boxWidth*2 + shipWidth;
+
+ pw.println("");
+ pw.println("\\begin{center}");
+ pw.println("\\begin{empfile}["+sd.getName()+"]");
+ pw.println("\\begin{emp}["+sd.getName()+"]("+(totalWidth+10)+","+(totalHeight+10)+")");
+ pw.println(" beginfig(1)");
+ pw.println(" pickup pencircle scaled 1pt;");
+ pw.println(" draw "+
+ "("+((totalWidth-shipWidth)/2)+","+0+")--"+
+ "("+((totalWidth-shipWidth)/2)+","+totalHeight+")--"+
+ "("+(totalWidth-((totalWidth-shipWidth)/2))+","+totalHeight+")--"+
+ "("+(totalWidth-((totalWidth-shipWidth)/2))+","+0+")--"+
+ "("+((totalWidth-shipWidth)/2)+","+0+");");
+ int left = 0;
+ int right = 0;
+ for(DockDescription bbd : sd) {
+ int ypos = (totalHeight - (boxGap/2) - (bbd.isLeft() ? left : right));
+ int half = (totalWidth-shipWidth)/2;
+ int p1 = bbd.isLeft() ? (half-5) : ((totalWidth-half)+5);
+ int p3 = bbd.isLeft() ? (p1 - boxWidth) : (p1 + boxWidth);
+ if (bbd.isInputDock()) {
+ int p1x = p1;
+ p1 = p3;
+ p3 = p1x;
+ }
+ boolean goo = ((bbd.isLeft() && bbd.isInputDock()) || (!bbd.isLeft() && bbd.isOutputDock()));
+ int p2 = goo ? (p3 - (boxHeight/2)) : (p3 + (boxHeight/2));
+ if (bbd.isLeft()) left += (boxHeight+boxGap);
+ else right += (boxHeight+boxGap);
+ if (goo) {
+ pw.println(" label.rt(btex \\tt "+bbd.getName()+" etex, ("+(p1+3)+","+(ypos-boxHeight/2)+"));");
+ } else {
+ pw.println(" label.lft(btex \\tt "+bbd.getName()+" etex, ("+(p1-3)+","+(ypos-boxHeight/2)+"));");
+ }
+ pw.println(" draw "+
+ " ("+p1+","+ypos+")--"+
+ " ("+p2+","+ypos+")--"+
+ " ("+p3+","+(ypos-(boxHeight/2))+")--"+
+ " ("+p2+","+(ypos-boxHeight)+")--"+
+ " ("+p1+","+(ypos-boxHeight)+")--"+
+ " ("+p1+","+ypos+");");
+ if (bbd.isLeft()) leftSize += boxHeight;
+ else rightSize += boxHeight;
+ }
+ pw.println(" endfig;");
+ pw.println("\\end{emp}");
+ pw.println("\\end{empfile}");
+ pw.println("\\end{center}");
+ pw.println("");
+
+ if (tex!=null)
+ pw.println(tex);
+ }
+
+ public class Constant {
+ public long setbits = 0;
+ public long clearbits = 0;
+ public boolean signExtend = false;
+ public int numberOffset = 0;
+ public int numberWidth = 0;
+ public Constant(String s) {
+ if (s.startsWith("0x")) {
+ setbits = Long.parseLong(s.substring(2), 16);
+ clearbits = ~setbits;
+ } else if (s.length() == 37) {
+ for(int i=36; i>=0; i--) {
+ char c = s.charAt(36-i);
+ switch(c) {
+ case '0': clearbits |= (1<<i); break;
+ case '1': setbits |= (1<<i); break;
+ case '.': break;
+ case 's': signExtend = true; numberOffset = i; numberWidth++; break;
+ case 'u': signExtend = false; numberOffset = i; numberWidth++; break;
+ }
+ }
+ } else {
+ setbits = Long.parseLong(s);
+ clearbits = ~setbits;
+ }
+ }
+ }
+
+}
throw new RuntimeException("bitfield width exceeded");
return doPutField(highBit, lowBit, val);
}
-}
\ No newline at end of file
+}
public final long val;
public final long valmask;
public final int valmaskmin;
+ public final int valmaskmax;
+ public final int valmaskwidth;
+ public final int allmax;
+ public final int width;
public String verilog(String var) {
- return "(("+var+" & "+mask+")=="+val+")";
+ // FIXME: throw an exception if this is called when no 1-bits or 0-bits were specified (ie only v-bits)
+ return "(("+var+" & "+allmax+"'b"+Long.toString(mask,2)+")=="+allmax+"'b"+Long.toString(val,2)+")";
}
public String verilogVal(String var) {
- return "(("+var+" & "+valmask+") >> "+valmaskmin+")";
+ //return "(("+var+" & "+allmax+"'b"+Long.toString(valmask,2)+") >> "+valmaskmin+")";
+ return ""+var+"["+valmaskmax+":"+valmaskmin+"]";
}
public long getval(long in) {
return (in & valmask) >>> valmaskmin;
}
+ public long setval(long in, BitVector targ) {
+ long ret = 0;
+ for(int i=0; i<targ.length(); i++)
+ if (targ.get(i))
+ ret |= (1L << i);
+ if (targ.get(targ.length()-1))
+ ret |= (-1L << targ.length());
+ return setval(in, ret);
+ }
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);
long valmask = 0;
long val = 0;
int valmaskmin = Integer.MAX_VALUE;
+ int valmaskmax = 0;
+ int allmax = 0;
+ this.width = s.length();
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;
+ case '0': mask |= (1L<<i); val |= (0L<<i); break;
+ case '1': mask |= (1L<<i); val |= (1L<<i); break;
+ case 'v': valmask |= (1L<<i); valmaskmin = Math.min(valmaskmin,i); valmaskmax = Math.max(valmaskmax,i); break;
default: throw new Error(""+c);
}
+ if (c!='.') allmax = Math.max(allmax,i);
}
this.mask = mask;
this.val = val;
this.valmask = valmask;
this.valmaskmin = valmaskmin;
+ this.valmaskmax = valmaskmax;
+ this.allmax = allmax+1;
+ this.valmaskwidth = 1 + valmaskmax - valmaskmin;
}
public static long signExtend(long input, int wordWidth) {
return input;
}
-}
\ No newline at end of file
+}