change div FSM pipeline unit to not have a combinatorial path directly from inputs...
authorJacob Lifshay <programmerjake@gmail.com>
Sun, 4 Oct 2020 22:17:41 +0000 (15:17 -0700)
committerJacob Lifshay <programmerjake@gmail.com>
Sun, 4 Oct 2020 22:17:41 +0000 (15:17 -0700)
Fixes #510

src/soc/fu/div/fsm.py

index 9083d6b99c7c787cb12039c2f6f0e35160d9fa82..2a78b19ad79258419c719e1dcba47789b529e674 100644 (file)
@@ -106,7 +106,14 @@ class DivState:
 
     @property
     def done(self):
 
     @property
     def done(self):
-        return self.q_bits_known == self.quotient_width
+        return self.will_be_done_after(steps=0)
+
+    def will_be_done_after(self, steps):
+        """ Returns 1 if this state will be done after
+            another `steps` passes through DivStateNext."""
+        assert isinstance(steps, int), "steps must be an integer"
+        assert steps >= 0
+        return self.q_bits_known >= max(0, self.quotient_width - steps)
 
     @property
     def quotient(self):
 
     @property
     def quotient(self):
@@ -160,7 +167,8 @@ class FSMDivCoreStage(ControlBase):
         rem_start = remainder_fract_width - dividend_fract_width
         m.d.comb += core_o.remainder.eq(self.div_state_next.o.remainder
                                         << rem_start)
         rem_start = remainder_fract_width - dividend_fract_width
         m.d.comb += core_o.remainder.eq(self.div_state_next.o.remainder
                                         << rem_start)
-        m.d.comb += self.n.valid_o.eq(~self.empty & self.div_state_next.o.done)
+        m.d.comb += self.n.valid_o.eq(
+            ~self.empty & self.saved_state.will_be_done_after(1))
         m.d.comb += self.p.ready_o.eq(self.empty)
         m.d.sync += self.saved_state.eq(self.div_state_next.o)
 
         m.d.comb += self.p.ready_o.eq(self.empty)
         m.d.sync += self.saved_state.eq(self.div_state_next.o)