corelogic: FSM
authorSebastien Bourdeauducq <sebastien@milkymist.org>
Mon, 9 Jan 2012 15:28:48 +0000 (16:28 +0100)
committerSebastien Bourdeauducq <sebastien@milkymist.org>
Mon, 9 Jan 2012 15:28:48 +0000 (16:28 +0100)
examples/fsm.py [new file with mode: 0644]
migen/corelogic/fsm.py [new file with mode: 0644]
migen/fhdl/structure.py

diff --git a/examples/fsm.py b/examples/fsm.py
new file mode 100644 (file)
index 0000000..2ee86e5
--- /dev/null
@@ -0,0 +1,9 @@
+from migen.fhdl.structure import *
+from migen.fhdl import verilog
+from migen.corelogic.fsm import FSM
+
+s = Signal()
+myfsm = FSM('FOO', 'BAR')
+myfsm.act(myfsm.FOO, s.eq(1), myfsm.next_state(myfsm.BAR))
+myfsm.act(myfsm.BAR, s.eq(0), myfsm.next_state(myfsm.FOO))
+print(verilog.convert(myfsm.get_fragment(), {s}))
diff --git a/migen/corelogic/fsm.py b/migen/corelogic/fsm.py
new file mode 100644 (file)
index 0000000..a3d3ccb
--- /dev/null
@@ -0,0 +1,29 @@
+from migen.fhdl.structure import *
+
+class FSM:
+       def __init__(self, *states):
+               self._state_bv = BV(bits_for(len(states)-1))
+               self._state = Signal(self._state_bv)
+               self._next_state = Signal(self._state_bv)
+               for state, n in zip(states, range(len(states))):
+                       setattr(self, state, Constant(n, self._state_bv))
+               self.actions = [[] for i in range(len(states))]
+       
+       def reset_state(self, state):
+               self._state.reset = state
+       
+       def next_state(self, state):
+               return self._next_state.eq(state)
+       
+       def act(self, state, *statements):
+               self.actions[state.n] += statements
+       
+       def get_fragment(self):
+               cases = [[Constant(s, self._state_bv)] + a
+                       for s, a in zip(range(len(self.actions)), self.actions) if a]
+               comb = [
+                       self._next_state.eq(self._state),
+                       Case(self._state, *cases)
+               ]
+               sync = [self._state.eq(self._next_state)]
+               return Fragment(comb, sync)
index 90b6e416e6b1321762d51052d5fb2c06d6a3dd91..354406c89936ecffa7a53c3630f7cc3c3271a802 100644 (file)
@@ -131,12 +131,14 @@ def _cst(x):
        else:
                return x
 
+_forbidden_prefixes = {'inst', 'source', 'sink', 'fsm'}
+
 def _try_class_name(frame):
        while frame is not None:
                try:
                        cl = frame.f_locals['self']
                        prefix = cl.__class__.__name__.lower()
-                       if prefix != 'inst' and prefix != 'source' and prefix != 'sink':
+                       if prefix not in _forbidden_prefixes:
                                return prefix
                except KeyError:
                        pass