Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: m-labs/migen
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 746acdacd1a9
Choose a base ref
...
head repository: m-labs/migen
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 72ef4b9683b0
Choose a head ref
  • 2 commits
  • 7 files changed
  • 1 contributor

Commits on Apr 10, 2013

  1. fhdl/visit: add TransformModule

    Sebastien Bourdeauducq committed Apr 10, 2013
    Copy the full SHA
    4c9018e View commit details
  2. ioo+pytholite: use new Module API

    Sebastien Bourdeauducq committed Apr 10, 2013
    Copy the full SHA
    72ef4b9 View commit details
Showing with 86 additions and 83 deletions.
  1. +9 −3 examples/pytholite/basic.py
  2. +15 −19 examples/pytholite/uio.py
  3. +8 −0 migen/fhdl/visit.py
  4. +16 −13 migen/genlib/ioo.py
  5. +30 −21 migen/pytholite/compiler.py
  6. +4 −15 migen/pytholite/io.py
  7. +4 −12 migen/pytholite/reg.py
12 changes: 9 additions & 3 deletions examples/pytholite/basic.py
Original file line number Diff line number Diff line change
@@ -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()
34 changes: 15 additions & 19 deletions examples/pytholite/uio.py
Original file line number Diff line number Diff line change
@@ -5,7 +5,7 @@
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,38 +37,34 @@ def __init__(self, ng):
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):
sim = Simulator(TestBench(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()
8 changes: 8 additions & 0 deletions migen/fhdl/visit.py
Original file line number Diff line number Diff line change
@@ -197,3 +197,11 @@ def visit_ArrayProxy(self, node):

def visit_unknown(self, node):
return node

class TransformModule:
def __init__(self, transform, module):
self.transform = transform
self.module = module

def get_fragment(self):
return self.transform(self.module.get_fragment())
29 changes: 16 additions & 13 deletions migen/genlib/ioo.py
Original file line number Diff line number Diff line change
@@ -1,41 +1,44 @@
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)
if isinstance(v, wishbone.Interface):
caller = wishbone.Initiator(g, v)
elif isinstance(v, Memory):
caller = memory.Initiator(g, v)
else:
raise NotImplementedError
callers.append(caller)
self.submodules += callers

51 changes: 30 additions & 21 deletions migen/pytholite/compiler.py
Original file line number Diff line number Diff line change
@@ -2,10 +2,13 @@
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 @@ def visit_expr_statement(self, sa, node):
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)
19 changes: 4 additions & 15 deletions migen/pytholite/io.py
Original file line number Diff line number Diff line change
@@ -3,25 +3,13 @@

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
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):
16 changes: 4 additions & 12 deletions migen/pytholite/reg.py
Original file line number Diff line number Diff line change
@@ -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,31 +21,22 @@ def visit_unknown(self, node):
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:
self.source_encoding[id(source)] = len(self.source_encoding) + 1
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)