2012-01-15 16:08:33 -05:00
|
|
|
from migen.fhdl.structure import *
|
2013-02-22 17:19:37 -05:00
|
|
|
from migen.genlib.record import *
|
|
|
|
from migen.genlib.fsm import *
|
2012-01-15 16:08:33 -05:00
|
|
|
from migen.flow.actor import *
|
|
|
|
|
|
|
|
# Generates integers from start to maximum-1
|
2012-06-22 09:01:47 -04:00
|
|
|
class IntSequence(Actor):
|
2012-07-06 18:10:23 -04:00
|
|
|
def __init__(self, nbits, offsetbits=0, step=1):
|
2012-06-17 15:19:47 -04:00
|
|
|
self.nbits = nbits
|
2012-07-06 18:10:23 -04:00
|
|
|
self.offsetbits = offsetbits
|
2012-01-15 16:08:33 -05:00
|
|
|
self.step = step
|
2012-06-17 15:19:47 -04:00
|
|
|
|
2012-11-29 15:22:38 -05:00
|
|
|
parameters_layout = [("maximum", self.nbits)]
|
2012-07-06 18:10:23 -04:00
|
|
|
if self.offsetbits:
|
2012-11-29 15:22:38 -05:00
|
|
|
parameters_layout.append(("offset", self.offsetbits))
|
2012-07-06 18:10:23 -04:00
|
|
|
|
2012-12-18 08:54:33 -05:00
|
|
|
Actor.__init__(self,
|
2012-07-06 18:10:23 -04:00
|
|
|
("parameters", Sink, parameters_layout),
|
2012-11-29 15:22:38 -05:00
|
|
|
("source", Source, [("value", max(self.nbits, self.offsetbits))]))
|
2012-01-15 16:08:33 -05:00
|
|
|
|
|
|
|
def get_fragment(self):
|
|
|
|
load = Signal()
|
|
|
|
ce = Signal()
|
|
|
|
last = Signal()
|
|
|
|
|
2012-11-29 15:22:38 -05:00
|
|
|
maximum = Signal(self.nbits)
|
2012-07-06 18:10:23 -04:00
|
|
|
if self.offsetbits:
|
2012-11-29 15:22:38 -05:00
|
|
|
offset = Signal(self.offsetbits)
|
|
|
|
counter = Signal(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),
|
2012-07-06 18:10:23 -04:00
|
|
|
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
|
|
|
]
|
2012-07-06 18:10:23 -04: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),
|
2012-07-06 18:10:23 -04:00
|
|
|
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()
|