add support for a "standing" count value
[fleet.git] / src / edu / berkeley / fleet / fpga / Generator.java
index b44a299..3132491 100644 (file)
@@ -150,6 +150,7 @@ public class Generator {
             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;
@@ -173,6 +174,7 @@ public class Generator {
             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;");
@@ -354,6 +356,10 @@ public class Generator {
             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;
@@ -462,8 +468,6 @@ public class Generator {
         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; "),
@@ -512,6 +516,18 @@ public class Generator {
         }
         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;
     }
@@ -563,11 +579,11 @@ public class Generator {
         }
 
         Module.Latch     ondeck         = box.new Latch("ondeck", WIDTH_WORD);
-        Module.Latch     repcount       = box.new Latch("repcount", WIDTH_COUNTER_LITERAL);
-        Module.Latch     repcount2      = box.new Latch("repcount2", WIDTH_COUNTER_LITERAL);
+        Module.Latch     repcount       = box.new Latch("repcount", WIDTH_COUNTER_LITERAL+1);
+        Module.Latch     repcount2      = box.new Latch("repcount2", WIDTH_COUNTER_LITERAL+1);
+        Module.Latch     repeat_counter = box.new Latch("repeat_counter", WIDTH_COUNTER_LITERAL+1);
         Module.Latch     killcount      = box.new Latch("killcount", WIDTH_COUNTER_LITERAL);
         Module.Latch     loop_counter   = box.new Latch("loop_counter", WIDTH_COUNTER_LITERAL);
-        Module.Latch     repeat_counter = box.new Latch("repeat_counter", WIDTH_COUNTER_LITERAL);
         Module.StateWire ondeckFull     = box.new StateWire("ondeck_full");
         Module.StateWire newMayProceed  = box.new StateWire("newmayproceed", true);
         Module.StateWire doRepeat       = box.new StateWire("dorepeat", false);
@@ -766,6 +782,19 @@ public class Generator {
                            new ConditionalAction("`should_requeue(ondeck)", ififo_in)
             }
             );
+        box.new Event(new Object[] { ondeckFull.isFull(),
+                                     isMassacreing.isEmpty(),
+                                     ififo_in,
+                                     "!`instruction_is_kill(instr)",
+                                     "`instruction_is_load_standing_to_repeat(ondeck)"
+            },
+            new Action[] { ondeckFull.doDrain(),
+                           newMayProceed.doFill(),
+                           new AssignAction(repeat_counter, "`magic_standing_value"),
+                           new ConditionalAction("`should_requeue(ondeck)", new AssignAction(ififo_in, ondeck)),
+                           new ConditionalAction("`should_requeue(ondeck)", ififo_in)
+            }
+            );
                            
                                      
         box.new Event(
@@ -784,9 +813,12 @@ public class Generator {
                                              new ConditionalAction("`done_executing(ondeck)",                            newMayProceed.doFill()),
                                              new ConditionalAction("`should_requeue(ondeck) && `done_executing(ondeck)", ififo_in),
                                              new ConditionalAction("`should_requeue(ondeck) && `done_executing(ondeck)", new AssignAction(ififo_in, ondeck)),
-                                             new ConditionalAction("repcount2>1", doRepeat.doFill()),
+                                             new ConditionalAction("repcount2>1 || repcount2==`magic_standing_value", doRepeat.doFill()),
                                              new ConditionalAction("`is_standing(ondeck)", doRepeat.doFill()),
-                                             new ConditionalAction("!`is_standing(ondeck)", new AssignAction(repcount, "repcount2-1")),
+                                             new ConditionalAction("!`is_standing(ondeck) && repcount2!=`magic_standing_value",
+                                                                   new AssignAction(repcount, "repcount2-1")),
+                                             new ConditionalAction("!`is_standing(ondeck) && repcount2==`magic_standing_value",
+                                                                   new AssignAction(repcount, "`magic_standing_value")),
                                              new ConditionalAction("`instruction_is_literal(ondeck)",
                                                                    new AssignAction(data_latch, "`instruction_literal(ondeck)")),
                                              new ConditionalAction("`instruction_is_literal_hi(ondeck)",
@@ -809,13 +841,14 @@ public class Generator {
 
         PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(prefix+"/"+name+".v")));
 
-        pw.println("`define instruction_is_load_loop_to_data(i)      "+TAKE_LOOP.verilog("i"));
-        pw.println("`define instruction_is_load_data_to_repeat(i)    "+REPEAT_FROM_DATA.verilog("i"));
-        pw.println("`define instruction_is_load_data_to_loop(i)      "+LOOP_FROM_DATA.verilog("i"));
-        pw.println("`define instruction_is_load_literal_to_repeat(i) "+REPEAT_FROM_LITERAL.verilog("i"));
-        pw.println("`define instruction_is_load_literal_to_loop(i)   "+LOOP_FROM_LITERAL.verilog("i"));
-        pw.println("`define instruction_repeat_count_literal(i)      "+REPEAT_FROM_LITERAL.verilogVal("i"));
-        pw.println("`define instruction_loop_count_literal(i)        "+LOOP_FROM_LITERAL.verilogVal("i"));
+        pw.println("`define instruction_is_load_loop_to_data(i)       "+TAKE_LOOP.verilog("i"));
+        pw.println("`define instruction_is_load_data_to_repeat(i)     "+REPEAT_FROM_DATA.verilog("i"));
+        pw.println("`define instruction_is_load_data_to_loop(i)       "+LOOP_FROM_DATA.verilog("i"));
+        pw.println("`define instruction_is_load_literal_to_repeat(i)  "+REPEAT_FROM_LITERAL.verilog("i"));
+        pw.println("`define instruction_is_load_literal_to_loop(i)    "+LOOP_FROM_LITERAL.verilog("i"));
+        pw.println("`define instruction_is_load_standing_to_repeat(i) "+REPEAT_FROM_STANDING.verilog("i"));
+        pw.println("`define instruction_repeat_count_literal(i)       "+REPEAT_FROM_LITERAL.verilogVal("i"));
+        pw.println("`define instruction_loop_count_literal(i)         "+LOOP_FROM_LITERAL.verilogVal("i"));
 
         pw.println("`define instruction_path_literal(i)              "+PATH_LITERAL.verilogVal("i"));
         pw.println("`define instruction_path_from_literal(i)         "+PATH_LITERAL.verilog("i"));
@@ -842,6 +875,8 @@ public class Generator {
         pw.println("`define should_requeue(i)               (loop_counter > 0)");
         pw.println("`define done_executing(i)               (!`is_standing(i) && (repcount2==0 || repcount2==1))");
 
+        pw.println("`define magic_standing_value            (1<<"+WIDTH_COUNTER_LITERAL+")");
+
         pw.println("`define instruction_literal_hi(i,d) { (i[17:0]),  (d[18:0]) }");
         pw.println("`define instruction_literal_lo(i,d) { (d[36:19]), (i[18:0]) }");