-import sys
import networkx as nx
from migen.fhdl import verilog
from migen.flow.ala import *
from migen.flow.network import *
-from migen.actorlib import dma_wishbone
+from migen.actorlib import dma_wishbone, control
L = [
("x", BV(10), 8),
])
]
+adrgen = control.For(10)
reader = dma_wishbone.Reader(L)
-frag = reader.get_fragment()
-print(verilog.convert(frag, ios=set(reader.bus.signals())))
+
+g = nx.MultiDiGraph()
+add_connection(g, adrgen, reader)
+comp = CompositeActor(g)
+
+frag = comp.get_fragment()
+ios = set(reader.bus.signals())
+ios.add(comp.busy)
+print(verilog.convert(frag, ios=ios))
--- /dev/null
+from operator import mul
+from functools import reduce
+
+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
+class For(Actor):
+ def __init__(self, *maxima, start=False, step=False):
+ self.dimensions = len(maxima)
+ self.start = start
+ self.step = step
+ params = ["end"]
+ if start: params.append("start")
+ if step: params.append("step")
+ self.d_bv = [BV(bits_for(dimension)) for dimension in maxima]
+ l_sink = [("d{0}".format(n), [(p, bv) for p in params])
+ for n, bv in zip(range(len(self.d_bv)), self.d_bv)]
+ l_source = [("d{0}".format(n), bv)
+ for n, bv in zip(range(len(self.d_bv)), self.d_bv)]
+ Actor.__init__(self, SchedulingModel(SchedulingModel.DYNAMIC),
+ ("sink", Sink, l_sink),
+ ("source", Source, l_source))
+
+ 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)]
+
+ 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]
+ 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)
+ ]
+ 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))
+ ]
+ counters_fragment = Fragment(sync=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))
+ )
+ 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))
+ )
+ )
+ return counters_fragment + fsm.get_fragment()