litex/migen/corelogic/fsm.py

43 lines
1.2 KiB
Python
Raw Normal View History

2012-01-09 10:28:48 -05:00
from migen.fhdl.structure import *
class FSM:
2012-03-17 19:09:40 -04:00
def __init__(self, *states, delayed_enters=[]):
nstates = len(states) + sum([d[2] for d in delayed_enters])
self._state_bv = BV(bits_for(nstates-1))
2012-01-09 10:28:48 -05:00
self._state = Signal(self._state_bv)
self._next_state = Signal(self._state_bv)
for n, state in enumerate(states):
2012-11-28 17:18:43 -05:00
setattr(self, state, n)
2012-01-09 10:28:48 -05:00
self.actions = [[] for i in range(len(states))]
2012-03-17 19:09:40 -04:00
for name, target, delay in delayed_enters:
target_state = getattr(self, target)
if delay:
name_state = len(self.actions)
2012-11-28 17:18:43 -05:00
setattr(self, name, name_state)
2012-03-17 19:09:40 -04:00
for i in range(delay-1):
2012-11-28 17:18:43 -05:00
self.actions.append([self.next_state(name_state+i+1)])
2012-03-17 19:09:40 -04:00
self.actions.append([self.next_state(target_state)])
else:
# alias
setattr(self, name, getattr(self, target_state))
2012-01-09 10:28:48 -05:00
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):
2012-11-28 17:18:43 -05:00
self.actions[state] += statements
2012-01-09 10:28:48 -05:00
def get_fragment(self):
2012-11-28 17:18:43 -05:00
cases = [[s] + a for s, a in enumerate(self.actions) if a]
2012-01-09 10:28:48 -05:00
comb = [
self._next_state.eq(self._state),
Case(self._state, *cases)
]
sync = [self._state.eq(self._next_state)]
return Fragment(comb, sync)