flow: simplify actor fragment interface
This commit is contained in:
parent
683e6b4a6c
commit
a6e5f3e766
|
@ -1,7 +1,7 @@
|
||||||
import sys
|
import sys
|
||||||
import networkx as nx
|
import networkx as nx
|
||||||
|
|
||||||
from migen.fhdl import verilog
|
from migen.fhdl import verilog
|
||||||
from migen.flow.ala import *
|
from migen.flow.ala import *
|
||||||
from migen.flow.network import *
|
from migen.flow.network import *
|
||||||
from migen.flow.composer import *
|
from migen.flow.composer import *
|
||||||
|
@ -13,7 +13,7 @@ a3 = make_composable(g, Add(BV(16)))
|
||||||
c3 = (a1 + a2)*a3
|
c3 = (a1 + a2)*a3
|
||||||
c = CompositeActor(g)
|
c = CompositeActor(g)
|
||||||
|
|
||||||
frag = c.get_control_fragment() + c.get_process_fragment()
|
frag = c.get_fragment()
|
||||||
|
|
||||||
print(verilog.convert(frag))
|
print(verilog.convert(frag))
|
||||||
|
|
||||||
|
|
|
@ -146,28 +146,26 @@ class Actor:
|
||||||
elif self.scheduling_model.model == SchedulingModel.PIPELINE:
|
elif self.scheduling_model.model == SchedulingModel.PIPELINE:
|
||||||
return _control_fragment_pipe(self.scheduling_model.latency, stb_i, ack_o, stb_o, ack_i, self.busy, self.pipe_ce)
|
return _control_fragment_pipe(self.scheduling_model.latency, stb_i, ack_o, stb_o, ack_i, self.busy, self.pipe_ce)
|
||||||
elif self.scheduling_model.model == SchedulingModel.DYNAMIC:
|
elif self.scheduling_model.model == SchedulingModel.DYNAMIC:
|
||||||
raise NotImplementedError("Actor classes with dynamic scheduling must overload get_control_fragment")
|
raise NotImplementedError("Actor classes with dynamic scheduling must overload get_control_fragment or get_fragment")
|
||||||
|
|
||||||
def get_process_fragment(self):
|
def get_process_fragment(self):
|
||||||
raise NotImplementedError("Actor classes must overload get_process_fragment")
|
raise NotImplementedError("Actor classes must overload get_process_fragment")
|
||||||
|
|
||||||
|
def get_fragment(self):
|
||||||
|
return self.get_control_fragment() + self.get_process_fragment()
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "<" + self.__class__.__name__ + " " + repr(self.scheduling_model) + " " + repr(self.sinks()) + " " + repr(self.sources()) + ">"
|
return "<" + self.__class__.__name__ + " " + repr(self.scheduling_model) + " " + repr(self.sinks()) + " " + repr(self.sources()) + ">"
|
||||||
|
|
||||||
def get_conn_control_fragment(source, sink):
|
def get_conn_fragment(source, sink):
|
||||||
assert isinstance(source, Source)
|
|
||||||
assert isinstance(sink, Sink)
|
|
||||||
comb = [
|
|
||||||
source.ack.eq(sink.ack),
|
|
||||||
sink.stb.eq(source.stb)
|
|
||||||
]
|
|
||||||
return Fragment(comb)
|
|
||||||
|
|
||||||
def get_conn_process_fragment(source, sink):
|
|
||||||
assert isinstance(source, Source)
|
assert isinstance(source, Source)
|
||||||
assert isinstance(sink, Sink)
|
assert isinstance(sink, Sink)
|
||||||
assert sink.token.compatible(source.token)
|
assert sink.token.compatible(source.token)
|
||||||
sigs_source = source.token.flatten()
|
sigs_source = source.token.flatten()
|
||||||
sigs_sink = sink.token.flatten()
|
sigs_sink = sink.token.flatten()
|
||||||
comb = [Cat(*sigs_sink).eq(Cat(*sigs_source))]
|
comb = [
|
||||||
|
source.ack.eq(sink.ack),
|
||||||
|
sink.stb.eq(source.stb),
|
||||||
|
Cat(*sigs_sink).eq(Cat(*sigs_source))
|
||||||
|
]
|
||||||
return Fragment(comb)
|
return Fragment(comb)
|
||||||
|
|
|
@ -20,18 +20,12 @@ class CompositeActor(Actor):
|
||||||
SchedulingModel(SchedulingModel.DYNAMIC),
|
SchedulingModel(SchedulingModel.DYNAMIC),
|
||||||
endpoints=our_endpoints)
|
endpoints=our_endpoints)
|
||||||
|
|
||||||
def get_control_fragment(self):
|
def get_fragment(self):
|
||||||
this = sum([get_conn_control_fragment(x[2]['source'], x[2]['sink'])
|
this = sum([get_conn_fragment(x[2]['source'], x[2]['sink'])
|
||||||
for x in self.dfg.edges(data=True)], Fragment())
|
for x in self.dfg.edges(data=True)], Fragment())
|
||||||
others = sum([node.get_control_fragment() for node in self.dfg], Fragment())
|
others = sum([node.get_fragment() for node in self.dfg], Fragment())
|
||||||
busy = Fragment([self.busy.eq(optree('|', [node.busy for node in self.dfg]))])
|
busy = Fragment([self.busy.eq(optree('|', [node.busy for node in self.dfg]))])
|
||||||
return this + others + busy
|
return this + others + busy
|
||||||
|
|
||||||
def get_process_fragment(self):
|
|
||||||
this = sum([get_conn_process_fragment(x[2]['source'], x[2]['sink'])
|
|
||||||
for x in self.dfg.edges(data=True)], Fragment())
|
|
||||||
others = sum([node.get_process_fragment() for node in self.dfg], Fragment())
|
|
||||||
return this + others
|
|
||||||
|
|
||||||
def add_connection(dfg, source_node, sink_node, source_ep=None, sink_ep=None):
|
def add_connection(dfg, source_node, sink_node, source_ep=None, sink_ep=None):
|
||||||
if source_ep is None:
|
if source_ep is None:
|
||||||
|
|
|
@ -25,10 +25,7 @@ class Combinator(Actor):
|
||||||
SchedulingModel(SchedulingModel.COMBINATORIAL),
|
SchedulingModel(SchedulingModel.COMBINATORIAL),
|
||||||
self.ins, self.destination)
|
self.ins, self.destination)
|
||||||
|
|
||||||
def get_process_fragment(self):
|
def get_fragment(self):
|
||||||
return Fragment() # nothing to do
|
|
||||||
|
|
||||||
def get_control_fragment(self):
|
|
||||||
source = self.sources()[0]
|
source = self.sources()[0]
|
||||||
sinks = self.sinks()
|
sinks = self.sinks()
|
||||||
comb = [source.stb.eq(optree('&', [sink.stb for sink in sinks]))]
|
comb = [source.stb.eq(optree('&', [sink.stb for sink in sinks]))]
|
||||||
|
@ -43,7 +40,4 @@ class Splitter(Actor):
|
||||||
SchedulingModel(SchedulingModel.COMBINATORIAL),
|
SchedulingModel(SchedulingModel.COMBINATORIAL),
|
||||||
self.source, self.outs)
|
self.source, self.outs)
|
||||||
|
|
||||||
def get_process_fragment(self):
|
# TODO def get_fragment(self):
|
||||||
return Fragment() # nothing to do
|
|
||||||
|
|
||||||
# TODO def get_control_fragment(self):
|
|
||||||
|
|
Loading…
Reference in New Issue