litex/migen/actorlib/misc.py

66 lines
1.5 KiB
Python

from migen.fhdl.structure import *
from migen.fhdl.module import Module
from migen.genlib.record import *
from migen.genlib.fsm import *
from migen.flow.actor import *
# Generates integers from start to maximum-1
class IntSequence(Module):
def __init__(self, nbits, offsetbits=0, step=1):
parameters_layout = [("maximum", nbits)]
if offsetbits:
parameters_layout.append(("offset", offsetbits))
self.parameters = Sink(parameters_layout)
self.source = Source([("value", max(nbits, offsetbits))])
self.busy = Signal()
###
load = Signal()
ce = Signal()
last = Signal()
maximum = Signal(nbits)
if offsetbits:
offset = Signal(offsetbits)
counter = Signal(nbits)
if step > 1:
self.comb += last.eq(counter + step >= maximum)
else:
self.comb += last.eq(counter + 1 == maximum)
self.sync += [
If(load,
counter.eq(0),
maximum.eq(self.parameters.payload.maximum),
offset.eq(self.parameters.payload.offset) if offsetbits else None
).Elif(ce,
If(last,
counter.eq(0)
).Else(
counter.eq(counter + step)
)
)
]
if offsetbits:
self.comb += self.source.payload.value.eq(counter + offset)
else:
self.comb += self.source.payload.value.eq(counter)
fsm = FSM("IDLE", "ACTIVE")
self.submodules += fsm
fsm.act(fsm.IDLE,
load.eq(1),
self.parameters.ack.eq(1),
If(self.parameters.stb, fsm.next_state(fsm.ACTIVE))
)
fsm.act(fsm.ACTIVE,
self.busy.eq(1),
self.source.stb.eq(1),
If(self.source.ack,
ce.eq(1),
If(last, fsm.next_state(fsm.IDLE))
)
)