eliminate a latch from every dock
authoradam <adam@megacz.com>
Mon, 27 Oct 2008 14:13:20 +0000 (15:13 +0100)
committeradam <adam@megacz.com>
Mon, 27 Oct 2008 14:13:20 +0000 (15:13 +0100)
src/edu/berkeley/fleet/fpga/FpgaDock.java

index 2f22f06..9d926a3 100644 (file)
@@ -86,27 +86,36 @@ public class FpgaDock extends FleetTwoDock implements FabricElement {
             Module.SourcePort ondeck_in = createInputPort ("ondeck_in",  WIDTH_WORD-DISPATCH_PATH.valmaskwidth);
             Module.SourcePort olc_in    = createInputPort ("olc_in",     SET_OLC_FROM_IMMEDIATE.valmaskwidth);
             Module.SinkPort   out       = createOutputPort("out",        WIDTH_WORD-DISPATCH_PATH.valmaskwidth, "");
-            out.hasLatch = true;
+            out.forceNoLatch = true;
 
-            Module.StateWire  using       = new StateWire("using", false);
-            Module.StateWire  circulating = new StateWire("circulating", false);
+            Module.StateWire  using         = new StateWire("using", false);
+            Module.StateWire  circulating   = new StateWire("circulating", false);
+            Module.StateWire  doResetFabric = new StateWire("doResetFabric", false);
+            Module.StateWire  doResetOndeck = new StateWire("doResetOndeck", false);
+
+            addPreCrap("assign out = "+circulating.isEmpty()+" ? "+fabric_in.getName()+" : "+ondeck_in.getName()+";");
 
             // always: discard one-shot instructions
             new Event(new Object[] { ondeck_in, /*olc_in,*/ OS.verilog(ondeck_in.getName()) },
                       new Action[] { ondeck_in, /*olc_in */});
 
+            new Event(new Object[] { doResetFabric.isFull(),  out },
+                      new Action[] { doResetFabric.doDrain(), fabric_in });
+            new Event(new Object[] { doResetOndeck.isFull(),  out },
+                      new Action[] { doResetOndeck.doDrain(), ondeck_in });
+
             new Event(new Object[] { circulating.isEmpty(),                  fabric_in, TAIL.verilog(fabric_in.getName()) },
                       new Action[] { circulating.doFill(),                   fabric_in });
-            new Event(new Object[] { circulating.isEmpty(),                  fabric_in, "!("+TAIL.verilog(fabric_in.getName())+")" },
-                      new Action[] {                                         fabric_in, out, new AssignAction(out, fabric_in) });
+            new Event(new Object[] { circulating.isEmpty(),                  fabric_in, "!("+TAIL.verilog(fabric_in.getName())+")", doResetFabric.isEmpty() },
+                      new Action[] {                                         out, doResetFabric.doFill() });
             new Event(new Object[] { using.isEmpty(),                        ondeck_in, /*olc_in,*/   "!("+OS.verilog(ondeck_in.getName())+")", "olc_in==0" },
                       new Action[] {                                         ondeck_in, /*olc_in */ });
             new Event(new Object[] { using.isEmpty(),                        ondeck_in, /*olc_in,*/   "!("+OS.verilog(ondeck_in.getName())+")", "olc_in!=0" },
                       new Action[] { using.doFill() });
             new Event(new Object[] { circulating.isFull(),  using.isFull(),  ondeck_in, /*olc_in,*/   "!("+OS.verilog(ondeck_in.getName())+")", "olc_in==0" },
                       new Action[] { circulating.doDrain(), using.doDrain(), ondeck_in, /*olc_in */});
-            new Event(new Object[] { circulating.isFull(),  using.isFull(),  ondeck_in, /*olc_in,*/   "!("+OS.verilog(ondeck_in.getName())+")", "olc_in!=0" },
-                      new Action[] {                                         ondeck_in, out, /*olc_in,*/ new AssignAction(out, ondeck_in) });
+            new Event(new Object[] { circulating.isFull(),  using.isFull(),  ondeck_in, /*olc_in,*/   "!("+OS.verilog(ondeck_in.getName())+")", "olc_in!=0", doResetOndeck.isEmpty() },
+                      new Action[] {                                         out, /*olc_in,*/ doResetOndeck.doFill() });
 
         }
     }