litex/migen/actorlib/misc.py

69 lines
1.8 KiB
Python
Raw Normal View History

2012-01-15 16:08:33 -05:00
from migen.fhdl.structure import *
from migen.corelogic.record import *
from migen.corelogic.fsm import *
from migen.flow.actor import *
# Generates integers from start to maximum-1
2012-06-22 09:01:47 -04:00
class IntSequence(Actor):
def __init__(self, nbits, offsetbits=0, step=1):
2012-06-17 15:19:47 -04:00
self.nbits = nbits
self.offsetbits = offsetbits
2012-01-15 16:08:33 -05:00
self.step = step
2012-06-17 15:19:47 -04:00
parameters_layout = [("maximum", BV(self.nbits))]
if self.offsetbits:
parameters_layout.append(("offset", BV(self.offsetbits)))
super().__init__(
("parameters", Sink, parameters_layout),
("source", Source, [("value", BV(max(self.nbits, self.offsetbits)))]))
2012-01-15 16:08:33 -05:00
def get_fragment(self):
load = Signal()
ce = Signal()
last = Signal()
2012-06-17 15:19:47 -04:00
maximum = Signal(BV(self.nbits))
if self.offsetbits:
offset = Signal(BV(self.offsetbits))
2012-06-17 15:19:47 -04:00
counter = Signal(BV(self.nbits))
2012-01-15 16:08:33 -05:00
2012-06-17 15:19:47 -04:00
if self.step > 1:
comb = [last.eq(counter + self.step >= maximum)]
2012-01-15 16:08:33 -05:00
else:
2012-06-17 15:19:47 -04:00
comb = [last.eq(counter + 1 == maximum)]
2012-01-15 16:08:33 -05:00
sync = [
If(load,
2012-06-17 15:19:47 -04:00
counter.eq(0),
maximum.eq(self.token("parameters").maximum),
offset.eq(self.token("parameters").offset) if self.offsetbits else None
2012-06-17 15:19:47 -04:00
).Elif(ce,
If(last,
counter.eq(0)
).Else(
counter.eq(counter + self.step)
)
)
2012-01-15 16:08:33 -05:00
]
if self.offsetbits:
comb.append(self.token("source").value.eq(counter + offset))
else:
comb.append(self.token("source").value.eq(counter))
2012-06-17 15:19:47 -04:00
counter_fragment = Fragment(comb, sync)
2012-01-15 16:08:33 -05:00
fsm = FSM("IDLE", "ACTIVE")
fsm.act(fsm.IDLE,
load.eq(1),
self.endpoints["parameters"].ack.eq(1),
If(self.endpoints["parameters"].stb, fsm.next_state(fsm.ACTIVE))
2012-01-15 16:08:33 -05:00
)
fsm.act(fsm.ACTIVE,
self.busy.eq(1),
self.endpoints["source"].stb.eq(1),
If(self.endpoints["source"].ack,
ce.eq(1),
If(last, fsm.next_state(fsm.IDLE))
)
)
2012-06-17 15:19:47 -04:00
return counter_fragment + fsm.get_fragment()