mirror of
https://github.com/enjoy-digital/litex.git
synced 2025-01-04 09:52:26 -05:00
corelogic: FSM
This commit is contained in:
parent
47ae303846
commit
b06e70d849
3 changed files with 41 additions and 1 deletions
9
examples/fsm.py
Normal file
9
examples/fsm.py
Normal file
|
@ -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}))
|
29
migen/corelogic/fsm.py
Normal file
29
migen/corelogic/fsm.py
Normal file
|
@ -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)
|
|
@ -131,12 +131,14 @@ def _cst(x):
|
||||||
else:
|
else:
|
||||||
return x
|
return x
|
||||||
|
|
||||||
|
_forbidden_prefixes = {'inst', 'source', 'sink', 'fsm'}
|
||||||
|
|
||||||
def _try_class_name(frame):
|
def _try_class_name(frame):
|
||||||
while frame is not None:
|
while frame is not None:
|
||||||
try:
|
try:
|
||||||
cl = frame.f_locals['self']
|
cl = frame.f_locals['self']
|
||||||
prefix = cl.__class__.__name__.lower()
|
prefix = cl.__class__.__name__.lower()
|
||||||
if prefix != 'inst' and prefix != 'source' and prefix != 'sink':
|
if prefix not in _forbidden_prefixes:
|
||||||
return prefix
|
return prefix
|
||||||
except KeyError:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
|
|
Loading…
Reference in a new issue