import edu.berkeley.fleet.two.*;
import static edu.berkeley.fleet.two.FleetTwoFleet.*;
import static edu.berkeley.fleet.fpga.verilog.Verilog.*;
-import static edu.berkeley.fleet.fpga.verilog.Verilog.PercolatedPort;
+import edu.berkeley.fleet.two.PercolatedPort;
public class Fpga extends FleetTwoFleet {
// Setup //////////////////////////////////////////////////////////////////////////////
Ship createShip(String type) throws IOException {
- ShipDescription sd = new ShipDescription(type, new BufferedReader(new InputStreamReader(new FileInputStream("ships/"+type+".ship"))));
+ ShipDescription sd = new ShipDescription(this, type, new BufferedReader(new InputStreamReader(new FileInputStream("ships/"+type+".ship"))));
int count = 0;
for(Ship ship : ships.values()) if (ship.getType().equals(type)) count++;
String name = type+count;
this.top = top;
debugShip = createShip("Debug");
- boolean small = true;
- //boolean small = false;
+ //boolean small = true;
+ boolean small = false;
if (small) {
+ for(int i=0; i<2; i++) createShip("Alu");
for(int i=0; i<1; i++) createShip("Memory");
for(int i=0; i<2; i++) createShip("Fifo");
- for(int i=0; i<2; i++) createShip("Alu");
createShip("Counter");
createShip("CarrySaveAdder");
createShip("Rotator");
createShip("Lut3");
- createShip("DDR2");
+
} else {
- for(int i=0; i<3; i++) createShip("Memory");
- for(int i=0; i<3; i++) createShip("Alu");
- for(int i=0; i<2; i++) createShip("Fifo");
- for(int i=0; i<14; i++) createShip("Counter");
- // "really big" configuration: 138 docks
- for(int i=0; i<10; i++) createShip("Alu");
- createShip("CarrySaveAdder");
- createShip("Rotator");
- createShip("Lut3");
+ for(int i=0; i<2; i++) createShip("Memory");
+ for(int i=0; i<8; i++) createShip("Alu");
+ for(int i=0; i<1; i++) createShip("Fifo");
+ for(int i=0; i<12; i++) createShip("Counter");
+
+ //createShip("CarrySaveAdder");
+ //createShip("Rotator");
+ createShip("Random");
+ createShip("Button");
- //createShip("DRAM");
- //createShip("Video");
}
+ createShip("Timer");
+ createShip("DDR2");
+ createShip("Dvi");
+
// for FifoShip
new Module.InstantiatedModule(top, new FifoModule(8, WIDTH_WORD));
final Module.SourcePort sp = sp0;
sources.add(new FabricElement.AbstractFabricElement() {
private FabricElement upstream;
+ public int getPathLength(FpgaDestination dest) { return upstream.getPathLength(dest); }
public FpgaPath getPath(FpgaDestination dest, BitVector signal) { return upstream.getPath(dest, signal); }
public void addOutput(FabricElement out, Module.Port outPort) {
this.upstream = out;
public void expand(ShipDescription sd) {
try {
if (sd.getSection("fpga")==null) return;
+ if (getShip(sd.getName(),0)==null) return; // no ships of this type
String filename = sd.getName().toLowerCase();
+
+ if (sd.getSection("ucf") != null) {
+ File outf = new File("build/fpga/"+filename+".ucf");
+ FileOutputStream out = new FileOutputStream(outf);
+ PrintWriter pw = new PrintWriter(out);
+ pw.println(sd.getSection("ucf"));
+ pw.flush();
+ pw.close();
+ }
+
File outf = new File("build/fpga/"+filename+".v");
new File(outf.getParent()).mkdirs();
System.err.println("writing to " + outf);
pw.println("`define "+name+"_full ("+name+"_r && !"+name+"_a)");
pw.println("`define "+name+"_empty (!"+name+"_r && !"+name+"_a)");
if (dd.isInputDock()) {
+ // gets stuck on colliding-tokens
+ //pw.println("`define drain_"+name+" if ("+name+"_r && !"+name+"_a) "+name+"_a <= 1;");
+
+ // gets stuck on colliding-tokens
+ //pw.println("`define drain_"+name+" if ("+name+"_r) "+name+"_a <= 1;");
+
+ // also gets stuck
+ //pw.println("`define drain_"+name+" if (!"+name+"_a) "+name+"_a <= 1;");
pw.println("`define drain_"+name+" "+name+"_a <= 1;");
} else {
pw.println("`define fill_"+name+" "+name+"_r <= 1;");
pw.print("`define reset ");
for(DockDescription bb : sd.ports()) {
String bb_name = bb.getName();
- if (bb.isInputDock()) pw.print(bb_name+"_a <= 1; "+bb_name+"_f <= 0; ");
+ if (bb.isInputDock()) pw.print(bb_name+"_a <= 1; ");
else pw.print(bb_name+"_r <= 0; ");
}
pw.println();
pw.print("`define cleanup ");
- for(DockDescription bb : sd.ports()) {
- String bb_name = bb.getName();
- if (bb.isInputDock()) pw.print("if (!"+bb_name+"_r && "+bb_name+"_a) "+bb_name+"_a <= 0; ");
- else pw.print("if ( "+bb_name+"_r && "+bb_name+"_a) "+bb_name+"_r <= 0; ");
- }
- pw.println();
- // FIXME: this corresponds to something
- /*
- pw.print("`define flush_happening (1");
+ // output docks
+ for(DockDescription dd : sd.ports())
+ if (!dd.isInputDock())
+ pw.print("if ( "+dd.getName()+"_r && "+dd.getName()+"_a) "+dd.getName()+"_r <= 0; ");
+
+ // input docks: if all inputs are flushing, drain them all
+ pw.print("if (1");
for(DockDescription bb : sd.ports())
if (bb.isInputDock())
- pw.print(" && "+bb.getName()+"_r_ && !"+bb.getName()+"_a && "+bb.getName()+"_d["+WIDTH_WORD+"]");
- pw.println(")");
- */
-
- pw.print("`define flush ");
+ pw.print(" && "+bb.getName()+"_f");
+ pw.print(") begin ");
for(DockDescription bb : sd.ports())
if (bb.isInputDock())
- pw.print(" if (!"+bb.getName()+"_r_) "+bb.getName()+"_f <= 0; ");
- pw.print("if (1");
+ pw.print(bb.getName()+"_a <= 1; ");
+
+ // input docks: if no inputs are flushing, do normal stuff
+ pw.print("end else if (1");
for(DockDescription bb : sd.ports())
if (bb.isInputDock())
- pw.print(" && "+bb.getName()+"_r_ && !"+bb.getName()+"_a");
+ pw.print(" && !"+bb.getName()+"_f");
pw.print(") begin ");
- if (true) {
- pw.print("if (1");
- for(DockDescription bb : sd.ports())
- if (bb.isInputDock())
- pw.print(" && "+bb.getName()+"_d["+WIDTH_WORD+"] ");
- pw.print(") begin ");
- if (true) {
- for(DockDescription bb : sd.ports())
- if (bb.isInputDock())
- pw.print(bb.getName()+"_f <= 1; ");
- }
- pw.print(" end else if (0");
- for(DockDescription bb : sd.ports())
- if (bb.isInputDock())
- pw.print(" || "+bb.getName()+"_d["+WIDTH_WORD+"] ");
- pw.print(") begin ");
- if (true) {
- for(DockDescription bb : sd.ports())
- if (bb.isInputDock())
- pw.print(" if (!"+bb.getName()+"_d["+WIDTH_WORD+"]) "+bb.getName()+"_f <= 1; ");
+
+ for(DockDescription bb : sd.ports())
+ if (bb.isInputDock())
+ pw.print("if (!"+bb.getName()+"_r_ && "+bb.getName()+"_a) "+bb.getName()+"_a <= 0; ");
+
+ // input docks: if some-but-not-all inputs are flushing, drain all non-flushing docks
+ pw.print("end else begin ");
+
+ for(DockDescription bb : sd.ports())
+ if (bb.isInputDock()) {
+ pw.print("if (!"+bb.getName()+"_r && "+bb.getName()+"_a) "+bb.getName()+"_a <= 0; ");
+ pw.print("if ("+bb.getName()+"_r && !"+bb.getName()+"_a) "+bb.getName()+"_a <= 1; ");
}
- pw.print(" end ");
- }
- pw.print(" end ");
+
+ pw.print(" end");
+
pw.println();
pw.println("module " + filename + "( clk, rst ");
pw.println(" output "+bb_name+"_a_;");
pw.println(" reg "+bb_name+"_a;");
pw.println(" initial "+bb_name+"_a = 0;");
- pw.println(" reg "+bb_name+"_f;");
- pw.println(" initial "+bb_name+"_f = 0;");
- pw.println(" assign "+bb_name+"_a_ = "+bb_name+"_a || "+bb_name+"_f;");
+ pw.println(" wire "+bb_name+"_f;");
+ pw.println(" assign "+bb_name+"_f = "+bb_name+"_r_ & "+bb_name+"_d["+width+"] && ~"+bb_name+"_a;");
+ pw.println(" assign "+bb_name+"_a_ = "+bb_name+"_a;");
} else {
pw.println(" output ["+width+":0] "+bb_name+"_d_;");
pw.println(" input "+bb_name+"_a;");
pw.println(" in_r, in_a__, in_d,");
pw.println(" out_r__, out_a, out_d_);");
pw.println(" always @(posedge clk) begin");
- pw.println(" if (!rst) begin");
+ pw.println(" if (rst) begin");
pw.println(" `reset");
pw.println(" end else begin");
- pw.println(" `flush");
+ pw.println(" `cleanup");
pw.println(" out_r <= out_r__;");
- pw.println(" in_a <= in_a__;");
+ pw.println(" if (in_a__) in_a <= 1;");
pw.println(" end");
pw.println(" end");
} else {