From: Sebastien Bourdeauducq Date: Wed, 10 Apr 2013 21:42:46 +0000 (+0200) Subject: ioo+pytholite: use new Module API X-Git-Tag: 24jan2021_ls180~2099^2~610 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=72ef4b9683b02a99495944f812ff9948c82fa031;p=litex.git ioo+pytholite: use new Module API --- diff --git a/examples/pytholite/basic.py b/examples/pytholite/basic.py index 621e61c9..857b22f2 100644 --- a/examples/pytholite/basic.py +++ b/examples/pytholite/basic.py @@ -1,7 +1,7 @@ from migen.flow.network import * from migen.flow.transactions import * from migen.actorlib.sim import * -from migen.pytholite.compiler import make_pytholite +from migen.pytholite.compiler import Pytholite from migen.sim.generic import Simulator from migen.fhdl import verilog @@ -26,17 +26,23 @@ def run_sim(ng): sim.run(30) del sim +def make_ng_pytholite(): + ng_pytholite = Pytholite(number_gen) + ng_pytholite.result = Source(layout) + ng_pytholite.finalize() + return ng_pytholite + def main(): print("Simulating native Python:") ng_native = SimNumberGen() run_sim(ng_native) print("Simulating Pytholite:") - ng_pytholite = make_pytholite(number_gen, dataflow=[("result", Source, layout)]) + ng_pytholite = make_ng_pytholite() run_sim(ng_pytholite) print("Converting Pytholite to Verilog:") - ng_pytholite = make_pytholite(number_gen, dataflow=[("result", Source, layout)]) + ng_pytholite = make_ng_pytholite() print(verilog.convert(ng_pytholite)) main() diff --git a/examples/pytholite/uio.py b/examples/pytholite/uio.py index 8519f7a0..edf26af0 100644 --- a/examples/pytholite/uio.py +++ b/examples/pytholite/uio.py @@ -5,7 +5,7 @@ from migen.bus import wishbone from migen.bus.transactions import * from migen.genlib.ioo import UnifiedIOSimulation from migen.pytholite.transel import Register -from migen.pytholite.compiler import make_pytholite +from migen.pytholite.compiler import Pytholite from migen.sim.generic import Simulator from migen.fhdl.module import Module from migen.fhdl.specials import Memory @@ -37,7 +37,7 @@ class TestBench(Module): g.add_connection(ng, d) self.submodules.slave = wishbone.Target(SlaveModel()) - self.submodules.intercon = wishbone.InterconnectPointToPoint(ng.buses["wb"], self.slave.bus) + self.submodules.intercon = wishbone.InterconnectPointToPoint(ng.wb, self.slave.bus) self.submodules.ca = CompositeActor(g) def run_sim(ng): @@ -45,30 +45,26 @@ def run_sim(ng): sim.run(50) del sim +def add_interfaces(obj): + obj.result = Source(layout) + obj.wb = wishbone.Interface() + obj.mem = Memory(32, 3, init=[42, 37, 81]) + obj.finalize() + def main(): - mem = Memory(32, 3, init=[42, 37, 81]) - dataflow = [("result", Source, layout)] - buses = { - "wb": wishbone.Interface(), - "mem": mem - } - print("Simulating native Python:") - ng_native = UnifiedIOSimulation(gen(), - dataflow=dataflow, - buses=buses) + ng_native = UnifiedIOSimulation(gen()) + add_interfaces(ng_native) run_sim(ng_native) print("Simulating Pytholite:") - ng_pytholite = make_pytholite(gen, - dataflow=dataflow, - buses=buses) + ng_pytholite = Pytholite(gen) + add_interfaces(ng_pytholite) run_sim(ng_pytholite) print("Converting Pytholite to Verilog:") - ng_pytholite = make_pytholite(gen, - dataflow=dataflow, - buses=buses) - print(verilog.convert(ng_pytholite.get_fragment())) + ng_pytholite = Pytholite(gen) + add_interfaces(ng_pytholite) + print(verilog.convert(ng_pytholite)) main() diff --git a/migen/genlib/ioo.py b/migen/genlib/ioo.py index 9257ad0b..20947d6a 100644 --- a/migen/genlib/ioo.py +++ b/migen/genlib/ioo.py @@ -1,32 +1,37 @@ from migen.fhdl.structure import * from migen.fhdl.specials import Memory from migen.flow.actor import * +from migen.flow.actor import _Endpoint from migen.flow.transactions import * from migen.actorlib.sim import TokenExchanger from migen.bus import wishbone, memory from migen.bus.transactions import * class UnifiedIOObject(Module): - def __init__(self, dataflow=None, buses={}): - if dataflow is not None: + def do_finalize(self): + if self.get_dataflow(): self.busy = Signal() - for name, cl, layout in dataflow: - setattr(self, name, cl(layout)) - self.buses = buses - self.specials += set(v for v in self.buses.values() if isinstance(v, Memory)) + self.specials += set(v for v in self.__dict__.values() if isinstance(v, Memory)) + + def get_dataflow(self): + return dict((k, v) for k, v in self.__dict__.items() if isinstance(v, _Endpoint)) + + def get_buses(self): + return dict((k, v) for k, v in self.__dict__.items() if isinstance(v, (wishbone.Interface, Memory))) (_WAIT_COMPLETE, _WAIT_POLL) = range(2) class UnifiedIOSimulation(UnifiedIOObject): - def __init__(self, generator, dataflow=None, buses={}): + def __init__(self, generator): self.generator = generator - UnifiedIOObject.__init__(self, dataflow, buses) - + + def do_finalize(self): + UnifiedIOObject.do_finalize(self) callers = [] self.busname_to_caller_id = {} - if dataflow is not None: + if self.get_dataflow(): callers.append(TokenExchanger(self.dispatch_g(0), self)) - for k, v in self.buses.items(): + for k, v in self.get_buses().items(): caller_id = len(callers) self.busname_to_caller_id[k] = caller_id g = self.dispatch_g(caller_id) @@ -34,8 +39,6 @@ class UnifiedIOSimulation(UnifiedIOObject): caller = wishbone.Initiator(g, v) elif isinstance(v, Memory): caller = memory.Initiator(g, v) - else: - raise NotImplementedError callers.append(caller) self.submodules += callers diff --git a/migen/pytholite/compiler.py b/migen/pytholite/compiler.py index 1faf1e10..1d450781 100644 --- a/migen/pytholite/compiler.py +++ b/migen/pytholite/compiler.py @@ -2,10 +2,13 @@ import inspect import ast from migen.fhdl.structure import * +from migen.fhdl.visit import TransformModule +from migen.fhdl.specials import Memory +from migen.genlib.ioo import UnifiedIOObject from migen.pytholite.reg import * from migen.pytholite.expr import * from migen.pytholite import transel -from migen.pytholite.io import Pytholite, gen_io +from migen.pytholite.io import gen_io from migen.pytholite.fsm import * def _is_name_used(node, name): @@ -226,23 +229,29 @@ class _Compiler: else: raise NotImplementedError -def make_pytholite(func, **ioresources): - ioo = Pytholite(**ioresources) - - tree = ast.parse(inspect.getsource(func)) - symdict = func.__globals__.copy() - registers = [] - - states = _Compiler(ioo, symdict, registers).visit_top(tree) - - regf = Fragment() - for register in registers: - if register.source_encoding: - register.finalize() - regf += register.get_fragment() - - fsm = implement_fsm(states) - fsmf = LowerAbstractLoad().visit(fsm.get_fragment()) - - ioo.fragment = regf + fsmf - return ioo +class Pytholite(UnifiedIOObject): + def __init__(self, func): + self.func = func + + def do_finalize(self): + UnifiedIOObject.do_finalize(self) + if self.get_dataflow(): + self.busy.reset = 1 + self.memory_ports = dict((mem, mem.get_port(write_capable=True, we_granularity=8)) + for mem in self.__dict__.values() if isinstance(mem, Memory)) + self._compile() + + def _compile(self): + tree = ast.parse(inspect.getsource(self.func)) + symdict = self.func.__globals__.copy() + registers = [] + + states = _Compiler(self, symdict, registers).visit_top(tree) + + for register in registers: + if register.source_encoding: + register.finalize() + self.submodules += register + + fsm = implement_fsm(states) + self.submodules += TransformModule(LowerAbstractLoad().visit, fsm) diff --git a/migen/pytholite/io.py b/migen/pytholite/io.py index c89cf791..6b6cbcb2 100644 --- a/migen/pytholite/io.py +++ b/migen/pytholite/io.py @@ -3,7 +3,6 @@ from itertools import zip_longest from migen.fhdl.structure import * from migen.fhdl.specials import Memory -from migen.genlib.ioo import UnifiedIOObject from migen.flow.actor import Source, Sink from migen.flow.transactions import * from migen.bus import wishbone @@ -11,17 +10,6 @@ from migen.bus.transactions import * from migen.pytholite.fsm import * from migen.pytholite.expr import ExprCompiler -class Pytholite(UnifiedIOObject): - def __init__(self, dataflow=None, buses={}): - UnifiedIOObject.__init__(self, dataflow, buses) - if dataflow is not None: - self.busy.reset = 1 - self.memory_ports = dict((mem, mem.get_port(write_capable=True, we_granularity=8)) - for mem in self.buses.values() if isinstance(mem, Memory)) - - def get_fragment(self): - return UnifiedIOObject.get_fragment(self) + self.fragment - class _TokenPullExprCompiler(ExprCompiler): def __init__(self, symdict, modelname, ep): ExprCompiler.__init__(self, symdict) @@ -151,11 +139,12 @@ def _gen_memory_io(compiler, modelname, model, to_model, from_model, port): def _gen_bus_io(compiler, modelname, model, to_model, from_model): busname = ast.literal_eval(to_model["busname"]) if busname is None: - if len(compiler.ioo.buses) != 1: + buses = compiler.ioo.get_buses() + if len(buses) != 1: raise TypeError("Bus name not specified") - bus = list(compiler.ioo.buses.values())[0] + bus = list(buses.values())[0] else: - bus = compiler.ioo.buses[busname] + bus = getattr(compiler.ioo, busname) if isinstance(bus, wishbone.Interface): return _gen_wishbone_io(compiler, modelname, model, to_model, from_model, bus) elif isinstance(bus, Memory): diff --git a/migen/pytholite/reg.py b/migen/pytholite/reg.py index 6346753d..175aa17e 100644 --- a/migen/pytholite/reg.py +++ b/migen/pytholite/reg.py @@ -1,6 +1,7 @@ from operator import itemgetter from migen.fhdl.structure import * +from migen.fhdl.module import Module from migen.fhdl import visit as fhdl class AbstractLoad: @@ -20,13 +21,12 @@ class LowerAbstractLoad(fhdl.NodeTransformer): else: return node -class ImplRegister: +class ImplRegister(Module): def __init__(self, name, bits_sign): self.name = name self.storage = Signal(bits_sign, name=self.name) self.source_encoding = {} self.id_to_source = {} - self.finalized = False def load(self, source): if id(source) not in self.source_encoding: @@ -34,17 +34,9 @@ class ImplRegister: self.id_to_source[id(source)] = source return AbstractLoad(self, source) - def finalize(self): - if self.finalized: - raise FinalizeError + def do_finalize(self): self.sel = Signal(max=len(self.source_encoding)+1, name="pl_regsel_"+self.name) - self.finalized = True - - def get_fragment(self): - if not self.finalized: - raise FinalizeError # do nothing when sel == 0 items = sorted(self.source_encoding.items(), key=itemgetter(1)) cases = dict((v, self.storage.eq(self.id_to_source[k])) for k, v in items) - sync = [Case(self.sel, cases)] - return Fragment(sync=sync) + self.sync += Case(self.sel, cases)