Commit a6e5f3e7 authored by Sebastien Bourdeauducq's avatar Sebastien Bourdeauducq
Browse files

flow: simplify actor fragment interface

parent 683e6b4a
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))) ...@@ -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: ...@@ -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): ...@@ -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): ...@@ -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): ...@@ -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):
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment