From: Sebastien Bourdeauducq Date: Sun, 17 Jun 2012 19:19:47 +0000 (+0200) Subject: actorlib/control: simplify + fix X-Git-Tag: 24jan2021_ls180~2099^2~904 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=1576cb0950d6cbcb9dcb4b9b5dd93a3033388859;p=litex.git actorlib/control: simplify + fix --- diff --git a/examples/dataflow/control.py b/examples/dataflow/control.py new file mode 100644 index 00000000..8819250e --- /dev/null +++ b/examples/dataflow/control.py @@ -0,0 +1,31 @@ +from migen.flow.network import * +from migen.actorlib import control +from migen.actorlib.sim import * +from migen.sim.generic import Simulator +from migen.sim.icarus import Runner + +def source_gen(): + for i in range(10): + v = i + 5 + print("==> " + str(v)) + yield Token("source", {"value": v}) + +def sink_gen(): + while True: + t = Token("sink") + yield t + print(t.value["value"]) + +def main(): + source = ActorNode(SimActor(source_gen(), ("source", Source, [("value", BV(32))]))) + loop = ActorNode(control.For(32)) + sink = ActorNode(SimActor(sink_gen(), ("sink", Sink, [("value", BV(32))]))) + g = DataFlowGraph() + g.add_connection(source, loop) + g.add_connection(loop, sink) + comp = CompositeActor(g) + fragment = comp.get_fragment() + sim = Simulator(fragment, Runner()) + sim.run(500) + +main() diff --git a/migen/actorlib/control.py b/migen/actorlib/control.py index 8520dd99..0d562cc0 100644 --- a/migen/actorlib/control.py +++ b/migen/actorlib/control.py @@ -1,6 +1,3 @@ -from operator import mul -from functools import reduce - from migen.fhdl.structure import * from migen.corelogic.record import * from migen.corelogic.fsm import * @@ -8,80 +5,46 @@ from migen.flow.actor import * # Generates integers from start to maximum-1 class For(Actor): - def __init__(self, *nbits, start=False, step=False): - self.dimensions = len(nbits) - self.start = start + def __init__(self, nbits, step=1): + self.nbits = nbits self.step = step - params = ["end"] - if start: params.append("start") - if step: params.append("step") - self.d_bv = [BV(dimension) for dimension in nbits] - l_sink = [("d{0}".format(n), [(p, bv) for p in params]) - for n, bv in enumerate(self.d_bv)] - l_source = [("d{0}".format(n), bv) - for n, bv in enumerate(self.d_bv)] + super().__init__( - ("sink", Sink, l_sink), - ("source", Source, l_source)) + ("maximum", Sink, [("value", BV(nbits))]), + ("source", Source, [("value", BV(nbits))])) def get_fragment(self): load = Signal() ce = Signal() last = Signal() - counters_v = [Signal(bv, variable=True) for bv in self.d_bv] - counters = [getattr(self.token("source"), "d{0}".format(n)) - for n in range(self.dimensions)] + maximum = Signal(BV(self.nbits)) + counter = Signal(BV(self.nbits)) - params = [getattr(self.token("sink"), "d{0}".format(n)) - for n in range(self.dimensions)] - if self.start: - starts = [p.start for p in params] - start_rs = [Signal(s.bv, variable=True) for s in starts] - else: - start_rs = [Constant(0, bv) for bv in self.d_bv] - if self.step: - steps = [p.step for p in params] - step_rs = [Signal(s.bv, variable=True) for s in steps] + if self.step > 1: + comb = [last.eq(counter + self.step >= maximum)] else: - step_rs = [Constant(1, bv) for bv in self.d_bv] - ends = [p.end for p in params] - end_rs = [Signal(s.bv, variable=True) for s in ends] - - lasts = Signal(BV(self.dimensions)) - - on_ce = [ - If(lasts[n], - counter.eq(start) - ).Else( - counter.eq(counter + step) - ) - for n, counter, start, step - in zip(range(self.dimensions), counters_v, start_rs, step_rs) - ] - lasts_gen = [ - lasts[n].eq(counter + step >= end if self.step else counter + step == end) - for n, counter, step, end - in zip(range(self.dimensions), counters_v, step_rs, end_rs) - ] + comb = [last.eq(counter + 1 == maximum)] sync = [ If(load, - Cat(*start_rs).eq(Cat(*starts)) if self.start else None, - Cat(*step_rs).eq(Cat(*steps)) if self.step else None, - Cat(*end_rs).eq(Cat(*ends)), - Cat(*counters_v).eq(Cat(*start_rs)) - ), - If(ce, *on_ce) - ] + lasts_gen + [ - Cat(*counters).eq(Cat(*counters_v)) + counter.eq(0), + maximum.eq(self.token("maximum").value) + ).Elif(ce, + If(last, + counter.eq(0) + ).Else( + counter.eq(counter + self.step) + ) + ) ] - counters_fragment = Fragment(sync=sync) + comb.append(self.token("source").value.eq(counter)) + counter_fragment = Fragment(comb, sync) fsm = FSM("IDLE", "ACTIVE") fsm.act(fsm.IDLE, load.eq(1), - self.endpoints["sink"].ack.eq(1), - If(self.endpoints["sink"].stb, fsm.next_state(fsm.ACTIVE)) + self.endpoints["maximum"].ack.eq(1), + If(self.endpoints["maximum"].stb, fsm.next_state(fsm.ACTIVE)) ) fsm.act(fsm.ACTIVE, self.busy.eq(1), @@ -91,4 +54,4 @@ class For(Actor): If(last, fsm.next_state(fsm.IDLE)) ) ) - return counters_fragment + fsm.get_fragment() + return counter_fragment + fsm.get_fragment()