Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- from collections import namedtuple, OrderedDict
- from migen.fhdl.std import *
- from migen.fhdl.visit import NodeTransformer
- class AnonymousState:
- pass
- NextState = namedtuple("NextState", "state")
- class _LowerNextState(NodeTransformer):
- def __init__(self, state_signal, next_state_signal, encoding, aliases):
- self.state_signal = state_signal
- self.next_state_signal = next_state_signal
- self.encoding = encoding
- self.aliases = aliases
- def visit_unknown(self, node):
- if isinstance(node, NextState):
- index = _index_is(self.states, node.target_state)
- estate = getattr(self.fsm, self.stnames[index])
- return self.fsm.next_state(estate)
- else:
- return node
- class FSM(Module):
- def __init__(self):
- self._actions = OrderedDict()
- self._state_aliases = dict()
- self.reset_state = None
- def act(self, state, *statements):
- if state not in self._actions:
- self._actions[state] = []
- self._actions[state] += statements
- def delayed_enter(self, name, target, delay):
- if delay:
- state = name
- for i in range(delay):
- if i == delay - 1:
- next_state = target
- else:
- next_state = AnonymousState()
- self.act(state, NextState(next_state))
- state = next_state
- else:
- self._state_aliases[name] = target
- def finalize(self):
- nstates = len(self._actions)
- encoding = dict((s, n) for n, s in enumerate(self._actions.keys()))
- state = Signal(max=nstates)
- next_state = Signal(max=nstates)
- lns = _LowerNextState(state, next_state, encoding, self._state_aliases)
- cases = dict((encoding[k], lns.visit(v)) for k, v in self._actions.items() if v)
- self.comb += [
- next_state.eq(state),
- Case(state, cases)
- ]
- self.sync += state.eq(next_state)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement