ioo+pytholite: use new Module API
authorSebastien Bourdeauducq <sebastien@milkymist.org>
Wed, 10 Apr 2013 21:42:46 +0000 (23:42 +0200)
committerSebastien Bourdeauducq <sebastien@milkymist.org>
Wed, 10 Apr 2013 21:42:46 +0000 (23:42 +0200)
examples/pytholite/basic.py
examples/pytholite/uio.py
migen/genlib/ioo.py
migen/pytholite/compiler.py
migen/pytholite/io.py
migen/pytholite/reg.py

index 621e61c946d5d14363993cf70b30a09d78ebe696..857b22f25c7aa0d85528e2d6806f0542135ca1bb 100644 (file)
@@ -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()
index 8519f7a0abce34057b017e47aed025cee62a74a5..edf26af0fb578a85726253fad1b670600bc4bccd 100644 (file)
@@ -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()
index 9257ad0b4d3b6d0ff9eea13eadd922e55cc778f4..20947d6aca0b3a6d7b94e660ee3952f46e78363f 100644 (file)
@@ -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
                
index 1faf1e108e07beaad86f70b4055ed81caf0fc3a0..1d4507816714d513c8d6629af258ab956f4557a7 100644 (file)
@@ -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)
index c89cf791819e3e81ae13bc8b573050cf211807cc..6b6cbcb27ccb9089c308bf033197c0136b512a21 100644 (file)
@@ -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):
index 6346753d0e0a40cd8bfc411a75d337741baf328b..175aa17e4f0dd52299070432769d6bef75c0ef52 100644 (file)
@@ -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)