added working test case for send-without-destination
[fleet.git] / src / edu / berkeley / fleet / fpga / Generator.java
index 95593d9..ba0bc7e 100644 (file)
@@ -406,7 +406,7 @@ public class Generator {
         pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(prefix+"/bitfields.v")));
         pw.println("`define DATAWIDTH                "+WIDTH_WORD);
         pw.println("`define CODEBAG_SIZE_BITS        "+WIDTH_CODEBAG_SIZE);
-        pw.println("`define BENKOBOX_ADDRESS_BITS    "+WIDTH_PUMP_ADDR);
+        pw.println("`define PUMP_ADDRESS_BITS    "+WIDTH_PUMP_ADDR);
         pw.println("`define DESTINATION_ADDRESS_BITS "+WIDTH_DEST_ADDR);
         pw.println("`define COUNT_BITS               "+WIDTH_COUNT);
         pw.println("`define COUNT_WIDTH              "+WIDTH_COUNT);
@@ -414,18 +414,51 @@ public class Generator {
         pw.println("`define INSTRUCTION_WIDTH        "+WIDTH_WORD);
         pw.println("`define packet_data(p)              p[(`DESTINATION_ADDRESS_BITS+`DATAWIDTH-1):(`DESTINATION_ADDRESS_BITS)]");
         pw.println("`define packet_dest(p)              p[(`DESTINATION_ADDRESS_BITS-1):0]");
+        pw.println("`define instruction_data(p)         p[(`DATAWIDTH-1):0]");
+        pw.println("`define instruction_dest(p)         p["+(OFFSET_PUMP_ADDR+WIDTH_PUMP_ADDR-1)+":"+OFFSET_PUMP_ADDR+"]");
         pw.flush();
         pw.close();
 
         mkfunnel("funnel", prefix);
         mkhorn(    "horn", prefix, WIDTH_PACKET-1, WIDTH_DEST_ADDR-1, 0, 0);
-        mkhorn(   "ihorn", prefix, WIDTH_PACKET-1, 34, 24, 0);
+        mkhorn(   "ihorn", prefix, WIDTH_PACKET-1, WIDTH_DEST_ADDR-1, 0, 0);
 
         Module fifostage = mkfifo("fifostage", 0, null,      prefix);
         Module fifo4     = mkfifo("fifo4",     4, fifostage, prefix);
         Module fifoship  = mkfifo("fifo",      4, fifo4,     prefix);
         mkBox("outbox", false, prefix, fifo4);
         mkBox("inbox", true, prefix, fifo4);
+
+        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.addPreCrap("initial count = 0;");
+        root.addPreCrap("initial count_out = 0;");
+        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);
+        pw.flush();
+        return root;
     }
 
     private static Module mkfunnel(String name, String prefix) throws Exception {
@@ -529,9 +562,9 @@ public class Generator {
         Module.SinkPort   ififo_in      = ififo.getInputPort("in");
         Module.SourcePort ififo_out     = ififo.getOutputPort("out");
 
-        Value instruction_count_ondeck        = ondeck  .getBits(1+WIDTH_DEST_ADDR+WIDTH_COUNT-1, 1+WIDTH_DEST_ADDR);
-        Value instruction_count_instr         = instr   .getBits(1+WIDTH_DEST_ADDR+WIDTH_COUNT-1, 1+WIDTH_DEST_ADDR);
-        Assignable instruction_count_ififo_in = ififo_in.getAssignableBits(1+WIDTH_DEST_ADDR+WIDTH_COUNT-1, 1+WIDTH_DEST_ADDR);
+        Value instruction_count_ondeck        = ondeck  .getBits(OFFSET_COUNT+WIDTH_COUNT-1, OFFSET_COUNT);
+        Value instruction_count_instr         = instr   .getBits(OFFSET_COUNT+WIDTH_COUNT-1, OFFSET_COUNT);
+        Assignable instruction_count_ififo_in = ififo_in.getAssignableBits(OFFSET_COUNT+WIDTH_COUNT-1, OFFSET_COUNT);
 
         // Clog (must be first)
         box.new Event(
@@ -625,12 +658,20 @@ public class Generator {
                                              new ConditionalAction("`instruction_bit_tokenout(ondeck)",
                                                                    new AssignAction(new SimpleAssignable("`packet_dest("+token_out.getName()+")"),
                                                                                     "`instruction_bit_dest(ondeck)")),
-                                             new ConditionalAction("`instruction_bit_dataout(ondeck)",
+                                             new ConditionalAction("`instruction_bit_dataout(ondeck) && !`instruction_bit_tokenout(ondeck)",
                                                                    inbox ? new SimpleAction("")
                                                                    : new AssignAction(new SimpleAssignable("`packet_dest("+data_out.getName()+")"),
-                                                                                      "`instruction_bit_dest(ondeck)"))
+                                                                                      "`instruction_bit_dest(ondeck)")),
+                                             new ConditionalAction("`instruction_bit_dataout(ondeck) && `instruction_bit_tokenout(ondeck) && !`instruction_bit_datain(ondeck)",
+                                                                   inbox ? new SimpleAction("")
+                                                                   : new AssignAction(new SimpleAssignable("`packet_dest("+data_out.getName()+")"),
+                                                                                      data_out.getName()+"["+(OFFSET_PUMP_ADDR+WIDTH_PUMP_ADDR-1)+":"+OFFSET_PUMP_ADDR+"]")),
+                                             new ConditionalAction("`instruction_bit_dataout(ondeck) && `instruction_bit_tokenout(ondeck) && `instruction_bit_datain(ondeck)",
+                                                                   inbox ? new SimpleAction("")
+                                                                   : new AssignAction(new SimpleAssignable("`packet_dest("+data_out.getName()+")"),
+                                                                                      data_latch_input+"["+(OFFSET_PUMP_ADDR+WIDTH_PUMP_ADDR-1)+":"+OFFSET_PUMP_ADDR+"]"))
                               }
-                              );
+                      );
 
         PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(prefix+"/"+name+".v")));
         pw.println("`define instruction_bit_tokenout(instruction) instruction["+OFFSET_TO+"]");