genlib/fsm: rename {entering,leaving} to after_{entering,leaving}, add before_{enteri...
authorRobert Jordens <jordens@gmail.com>
Thu, 21 Nov 2013 19:44:01 +0000 (12:44 -0700)
committerSebastien Bourdeauducq <sebastien@milkymist.org>
Thu, 21 Nov 2013 22:30:24 +0000 (23:30 +0100)
examples/basic/fsm.py
migen/genlib/fsm.py

index 7dd1ba250c105fc966d2f0e31143fd114b201a54..435aaa4b08dfc720a7b26d9db7ba2f8569c43159 100644 (file)
@@ -9,8 +9,10 @@ class Example(Module):
                self.submodules += myfsm
                myfsm.act("FOO", self.s.eq(1), NextState("BAR"))
                myfsm.act("BAR", self.s.eq(0), NextState("FOO"))
-               self.entering_foo = myfsm.entering("FOO")
-               self.leaving_bar = myfsm.leaving("BAR")
+               self.be = myfsm.before_entering("FOO")
+               self.ae = myfsm.after_entering("FOO")
+               self.bl = myfsm.before_leaving("FOO")
+               self.al = myfsm.after_leaving("FOO")
 
 example = Example()
-print(verilog.convert(example, {example.s, example.entering_foo, example.leaving_bar}))
+print(verilog.convert(example, {example.s, example.be, example.ae, example.bl, example.al}))
index e4ee94f961aef226a4ee17e674bae21d0ae93444..8818fe64673a9297dcc50506bdcd0acb6b3d3b03 100644 (file)
@@ -35,8 +35,10 @@ class FSM(Module):
                self.state_aliases = dict()
                self.reset_state = reset_state
 
-               self.entering_signals = OrderedDict()
-               self.leaving_signals = OrderedDict()
+               self.before_entering_signals = OrderedDict()
+               self.before_leaving_signals = OrderedDict()
+               self.after_entering_signals = OrderedDict()
+               self.after_leaving_signals = OrderedDict()
 
        def act(self, state, *statements):
                if self.finalized:
@@ -65,7 +67,7 @@ class FSM(Module):
                self.act(state, is_ongoing.eq(1))
                return is_ongoing
 
-       def _entering_leaving(self, d, state):
+       def _get_signal(self, d, state):
                if state not in self.actions:
                        self.actions[state] = []
                try:
@@ -75,12 +77,22 @@ class FSM(Module):
                        d[state] = is_el
                        return is_el
 
-       def entering(self, state):
-               return self._entering_leaving(self.entering_signals, state)
+       def before_entering(self, state):
+               return self._get_signal(self.before_entering_signals, state)
+
+       def before_leaving(self, state):
+               return self._get_signal(self.before_leaving_signals, state)
+
+       def after_entering(self, state):
+               signal = self._get_signal(self.after_entering_signals, state)
+               self.sync += signal.eq(self.before_entering(state))
+               return signal
+
+       def after_leaving(self, state):
+               signal = self._get_signal(self.after_leaving_signals, state)
+               self.sync += signal.eq(self.before_leaving(state))
+               return signal
 
-       def leaving(self, state):
-               return self._entering_leaving(self.leaving_signals, state)
-       
        def do_finalize(self):
                nstates = len(self.actions)
                if self.reset_state is None:
@@ -101,11 +113,11 @@ class FSM(Module):
                self.sync += self.state.eq(self.next_state)
 
                # drive entering/leaving signals
-               for state, is_entering in self.entering_signals.items():
+               for state, signal in self.before_leaving_signals.items():
                        encoded = self.encoding[state]
-                       self.sync += is_entering.eq((self.next_state == encoded) & (self.state != encoded))
-               if reset_state in self.entering_signals:
-                       self.entering_signals[reset_state].reset = 1
-               for state, is_leaving in self.leaving_signals.items():
+                       self.comb += signal.eq((self.state == encoded) & ~(self.next_state == encoded))
+               if reset_state in self.after_entering_signals:
+                       self.after_entering_signals[reset_state].reset = 1
+               for state, signal in self.before_entering_signals.items():
                        encoded = self.encoding[state]
-                       self.sync += is_leaving.eq((self.next_state != encoded) & (self.state == encoded))
+                       self.comb += signal.eq(~(self.state == encoded) & (self.next_state == encoded))