From 1051878f4c10a1226bbad2648864771f3e076afb Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Mon, 13 Apr 2015 20:45:35 +0200 Subject: [PATCH] global: pep8 (E302) --- examples/basic/arrays.py | 1 + examples/basic/complex.py | 1 + examples/basic/fsm.py | 1 + examples/basic/graycounter.py | 1 + examples/basic/local_cd.py | 2 ++ examples/basic/memory.py | 1 + examples/basic/namer.py | 5 +++++ examples/basic/psync.py | 2 ++ examples/basic/record.py | 1 + examples/basic/reslice.py | 1 + examples/basic/simple_gpio.py | 1 + examples/basic/tristate.py | 1 + examples/basic/two_dividers.py | 1 + examples/dataflow/dma.py | 13 +++++++++++++ examples/dataflow/misc.py | 4 ++++ examples/dataflow/structuring.py | 5 +++++ examples/sim/abstract_transactions_wb.py | 3 +++ examples/sim/basic1.py | 1 + examples/sim/basic2.py | 1 + examples/sim/dataflow.py | 5 +++++ examples/sim/fir.py | 2 ++ examples/sim/memory.py | 1 + mibuild/altera/platform.py | 1 + mibuild/altera/programmer.py | 1 + mibuild/altera/quartus.py | 6 ++++++ mibuild/generic_platform.py | 13 +++++++++++++ mibuild/generic_programmer.py | 1 + mibuild/lattice/common.py | 4 ++++ mibuild/lattice/diamond.py | 6 ++++++ mibuild/lattice/platform.py | 1 + mibuild/lattice/programmer.py | 1 + mibuild/platforms/apf27.py | 1 + mibuild/platforms/apf51.py | 1 + mibuild/platforms/de0nano.py | 1 + mibuild/platforms/kc705.py | 1 + mibuild/platforms/m1.py | 1 + mibuild/platforms/minispartan6.py | 1 + mibuild/platforms/mixxeo.py | 1 + mibuild/platforms/ml605.py | 1 + mibuild/platforms/papilio_pro.py | 1 + mibuild/platforms/pipistrello.py | 1 + mibuild/platforms/rhino.py | 1 + mibuild/platforms/roach.py | 1 + mibuild/platforms/sim.py | 2 ++ mibuild/platforms/versa.py | 1 + mibuild/platforms/ztex_115d.py | 1 + mibuild/sim/platform.py | 1 + mibuild/sim/verilator.py | 4 ++++ mibuild/tools.py | 5 +++++ mibuild/xilinx/common.py | 13 +++++++++++++ mibuild/xilinx/ise.py | 7 +++++++ mibuild/xilinx/platform.py | 1 + mibuild/xilinx/programmer.py | 8 ++++++++ mibuild/xilinx/vivado.py | 5 +++++ migen/actorlib/dma_wishbone.py | 2 ++ migen/actorlib/fifo.py | 3 +++ migen/actorlib/misc.py | 1 + migen/actorlib/sim.py | 6 ++++++ migen/actorlib/spi.py | 6 ++++++ migen/actorlib/structuring.py | 9 +++++++++ migen/bank/bank.py | 2 ++ migen/bank/csrgen.py | 2 ++ migen/bank/description.py | 8 ++++++++ migen/bank/eventmanager.py | 6 ++++++ migen/bank/wbgen.py | 1 + migen/bus/csr.py | 4 ++++ migen/bus/memory.py | 2 ++ migen/bus/transactions.py | 3 +++ migen/bus/wishbone.py | 12 ++++++++++++ migen/bus/wishbone2csr.py | 1 + migen/fhdl/bitcontainer.py | 7 +++++++ migen/fhdl/decorators.py | 6 ++++++ migen/fhdl/edif.py | 10 ++++++++++ migen/fhdl/module.py | 12 ++++++++++++ migen/fhdl/namer.py | 14 ++++++++++++++ migen/fhdl/simplify.py | 1 + migen/fhdl/specials.py | 7 +++++++ migen/fhdl/structure.py | 20 ++++++++++++++++++++ migen/fhdl/tools.py | 23 +++++++++++++++++++++++ migen/fhdl/tracer.py | 5 +++++ migen/fhdl/verilog.py | 14 ++++++++++++++ migen/fhdl/visit.py | 2 ++ migen/flow/actor.py | 10 ++++++++++ migen/flow/hooks.py | 2 ++ migen/flow/isd.py | 2 ++ migen/flow/network.py | 4 ++++ migen/flow/perftools.py | 2 ++ migen/flow/plumbing.py | 5 +++++ migen/genlib/cdc.py | 5 +++++ migen/genlib/coding.py | 4 ++++ migen/genlib/complex.py | 2 ++ migen/genlib/divider.py | 1 + migen/genlib/fifo.py | 5 +++++ migen/genlib/fsm.py | 5 +++++ migen/genlib/io.py | 5 +++++ migen/genlib/misc.py | 8 ++++++++ migen/genlib/record.py | 5 +++++ migen/genlib/resetsync.py | 1 + migen/genlib/rob.py | 2 ++ migen/genlib/roundrobin.py | 1 + migen/genlib/sort.py | 1 + migen/sim/generic.py | 3 +++ migen/sim/ipc.py | 16 ++++++++++++++++ migen/sim/upper.py | 3 +++ migen/test/support.py | 2 ++ migen/test/test_actor.py | 6 ++++++ migen/test/test_coding.py | 4 ++++ migen/test/test_fifo.py | 1 + migen/test/test_signed.py | 1 + migen/test/test_size.py | 2 ++ migen/test/test_sort.py | 1 + migen/util/misc.py | 4 ++++ migen/util/treeviz.py | 4 ++++ 113 files changed, 454 insertions(+) diff --git a/examples/basic/arrays.py b/examples/basic/arrays.py index 7049b520..5141d8ec 100644 --- a/examples/basic/arrays.py +++ b/examples/basic/arrays.py @@ -1,6 +1,7 @@ from migen.fhdl.std import * from migen.fhdl import verilog + class Example(Module): def __init__(self): dx = 2 diff --git a/examples/basic/complex.py b/examples/basic/complex.py index 60479ab6..8f654f81 100644 --- a/examples/basic/complex.py +++ b/examples/basic/complex.py @@ -2,6 +2,7 @@ from migen.fhdl.std import * from migen.genlib.complex import * from migen.fhdl import verilog + class Example(Module): def __init__(self): w = Complex(32, 42) diff --git a/examples/basic/fsm.py b/examples/basic/fsm.py index bb85b03a..4c2c8792 100644 --- a/examples/basic/fsm.py +++ b/examples/basic/fsm.py @@ -2,6 +2,7 @@ from migen.fhdl.std import * from migen.fhdl import verilog from migen.genlib.fsm import FSM, NextState, NextValue + class Example(Module): def __init__(self): self.s = Signal() diff --git a/examples/basic/graycounter.py b/examples/basic/graycounter.py index 8d330a51..8a0f7243 100644 --- a/examples/basic/graycounter.py +++ b/examples/basic/graycounter.py @@ -4,6 +4,7 @@ from migen.fhdl.std import * from migen.genlib.cdc import GrayCounter from migen.sim.generic import run_simulation + class TB(Module): def __init__(self, width=3): self.width = width diff --git a/examples/basic/local_cd.py b/examples/basic/local_cd.py index 97edf339..3fddcec5 100644 --- a/examples/basic/local_cd.py +++ b/examples/basic/local_cd.py @@ -2,11 +2,13 @@ from migen.fhdl.std import * from migen.fhdl import verilog from migen.genlib.divider import Divider + class CDM(Module): def __init__(self): self.submodules.divider = Divider(5) self.clock_domains.cd_sys = ClockDomain(reset_less=True) + class MultiMod(Module): def __init__(self): self.submodules.foo = CDM() diff --git a/examples/basic/memory.py b/examples/basic/memory.py index bd26f948..e20b4a9f 100644 --- a/examples/basic/memory.py +++ b/examples/basic/memory.py @@ -1,6 +1,7 @@ from migen.fhdl.std import * from migen.fhdl import verilog + class Example(Module): def __init__(self): self.specials.mem = Memory(32, 100, init=[5, 18, 32]) diff --git a/examples/basic/namer.py b/examples/basic/namer.py index a614cab7..0983520e 100644 --- a/examples/basic/namer.py +++ b/examples/basic/namer.py @@ -2,24 +2,29 @@ from migen.fhdl.std import * from migen.fhdl import verilog from migen.genlib.misc import optree + def gen_list(n): s = [Signal() for i in range(n)] return s + def gen_2list(n): s = [Signal(2) for i in range(n)] return s + class Foo: def __init__(self): la = gen_list(3) lb = gen_2list(2) self.sigs = la + lb + class Bar: def __init__(self): self.sigs = gen_list(2) + class Example(Module): def __init__(self): a = [Bar() for x in range(3)] diff --git a/examples/basic/psync.py b/examples/basic/psync.py index 67467d25..64f704f8 100644 --- a/examples/basic/psync.py +++ b/examples/basic/psync.py @@ -3,12 +3,14 @@ from migen.fhdl.specials import SynthesisDirective from migen.fhdl import verilog from migen.genlib.cdc import * + class XilinxMultiRegImpl(MultiRegImpl): def __init__(self, *args, **kwargs): MultiRegImpl.__init__(self, *args, **kwargs) self.specials += set(SynthesisDirective("attribute shreg_extract of {r} is no", r=r) for r in self.regs) + class XilinxMultiReg: @staticmethod def lower(dr): diff --git a/examples/basic/record.py b/examples/basic/record.py index c5cc26f1..7b31a18c 100644 --- a/examples/basic/record.py +++ b/examples/basic/record.py @@ -12,6 +12,7 @@ L = [ ("ack", 1, DIR_S_TO_M) ] + class Test(Module): def __init__(self): master = Record(L) diff --git a/examples/basic/reslice.py b/examples/basic/reslice.py index b6ee48cf..a86f75af 100644 --- a/examples/basic/reslice.py +++ b/examples/basic/reslice.py @@ -1,6 +1,7 @@ from migen.fhdl.std import * from migen.fhdl import verilog + class Example(Module): def __init__(self): a = Signal(3) diff --git a/examples/basic/simple_gpio.py b/examples/basic/simple_gpio.py index 631e4bb6..a9d2a8a8 100644 --- a/examples/basic/simple_gpio.py +++ b/examples/basic/simple_gpio.py @@ -3,6 +3,7 @@ from migen.fhdl import verilog from migen.genlib.cdc import MultiReg from migen.bank import description, csrgen + class Example(Module): def __init__(self, ninputs=32, noutputs=32): r_o = description.CSRStorage(noutputs, atomic_write=True) diff --git a/examples/basic/tristate.py b/examples/basic/tristate.py index af181697..9359aaa0 100644 --- a/examples/basic/tristate.py +++ b/examples/basic/tristate.py @@ -1,6 +1,7 @@ from migen.fhdl.std import * from migen.fhdl import verilog + class Example(Module): def __init__(self, n=6): self.pad = Signal(n) diff --git a/examples/basic/two_dividers.py b/examples/basic/two_dividers.py index d895bf70..5e70cfbe 100644 --- a/examples/basic/two_dividers.py +++ b/examples/basic/two_dividers.py @@ -2,6 +2,7 @@ from migen.fhdl.std import * from migen.fhdl import verilog from migen.genlib import divider + @ResetInserter() @CEInserter() class Example(Module): diff --git a/examples/dataflow/dma.py b/examples/dataflow/dma.py index 99190a91..121fbb74 100644 --- a/examples/dataflow/dma.py +++ b/examples/dataflow/dma.py @@ -8,10 +8,12 @@ from migen.actorlib.sim import * from migen.bus import wishbone from migen.sim.generic import run_simulation + class MyModel: def read(self, address): return address + 4 + class MyModelWB(MyModel, wishbone.TargetModel): def __init__(self): self.prng = Random(763627) @@ -19,27 +21,32 @@ class MyModelWB(MyModel, wishbone.TargetModel): def can_ack(self, bus): return self.prng.randrange(0, 2) + def adrgen_gen(): for i in range(10): print("Address: " + hex(i)) yield Token("address", {"a": i}) + class SimAdrGen(SimActor): def __init__(self, nbits): self.address = Source([("a", nbits)]) SimActor.__init__(self, adrgen_gen()) + def dumper_gen(): while True: t = Token("data", idle_wait=True) yield t print("Received: " + hex(t.value["d"])) + class SimDumper(SimActor): def __init__(self): self.data = Sink([("d", 32)]) SimActor.__init__(self, dumper_gen()) + def trgen_gen(): for i in range(10): a = i @@ -47,11 +54,13 @@ def trgen_gen(): print("Address: " + hex(a) + " Data: " + hex(d)) yield Token("address_data", {"a": a, "d": d}) + class SimTrGen(SimActor): def __init__(self, a_nbits): self.address_data = Source([("a", a_nbits), ("d", 32)]) SimActor.__init__(self, trgen_gen()) + class TBWishbone(Module): def __init__(self, master): self.submodules.peripheral = wishbone.Target(MyModelWB()) @@ -59,6 +68,7 @@ class TBWishbone(Module): self.submodules.interconnect = wishbone.InterconnectPointToPoint(master.bus, self.peripheral.bus) + class TBWishboneReader(TBWishbone): def __init__(self): self.adrgen = SimAdrGen(30) @@ -70,6 +80,7 @@ class TBWishboneReader(TBWishbone): self.submodules.comp = CompositeActor(g) TBWishbone.__init__(self, self.reader) + class TBWishboneWriter(TBWishbone): def __init__(self): self.trgen = SimTrGen(30) @@ -79,10 +90,12 @@ class TBWishboneWriter(TBWishbone): self.submodules.comp = CompositeActor(g) TBWishbone.__init__(self, self.writer) + def test_wb_reader(): print("*** Testing Wishbone reader") run_simulation(TBWishboneReader(), 100) + def test_wb_writer(): print("*** Testing Wishbone writer") run_simulation(TBWishboneWriter(), 100) diff --git a/examples/dataflow/misc.py b/examples/dataflow/misc.py index 095ca3ef..475997e2 100644 --- a/examples/dataflow/misc.py +++ b/examples/dataflow/misc.py @@ -4,23 +4,27 @@ from migen.actorlib import misc from migen.actorlib.sim import * from migen.sim.generic import run_simulation + def source_gen(): for i in range(10): v = i + 5 print("==> " + str(v)) yield Token("source", {"maximum": v}) + class SimSource(SimActor): def __init__(self): self.source = Source([("maximum", 32)]) SimActor.__init__(self, source_gen()) + def sink_gen(): while True: t = Token("sink") yield t print(t.value["value"]) + class SimSink(SimActor): def __init__(self): self.sink = Sink([("value", 32)]) diff --git a/examples/dataflow/structuring.py b/examples/dataflow/structuring.py index b1b6574e..db2758ee 100644 --- a/examples/dataflow/structuring.py +++ b/examples/dataflow/structuring.py @@ -15,26 +15,31 @@ base_layout = [("value", 32)] packed_layout = structuring.pack_layout(base_layout, pack_factor) rawbits_layout = [("value", 32*pack_factor)] + def source_gen(): for i in count(0): yield Token("source", {"value": i}) + class SimSource(SimActor): def __init__(self): self.source = Source(base_layout) SimActor.__init__(self, source_gen()) + def sink_gen(): while True: t = Token("sink") yield t print(t.value["value"]) + class SimSink(SimActor): def __init__(self): self.sink = Sink(base_layout) SimActor.__init__(self, sink_gen()) + class TB(Module): def __init__(self): source = SimSource() diff --git a/examples/sim/abstract_transactions_wb.py b/examples/sim/abstract_transactions_wb.py index 084876c9..bc22cc41 100644 --- a/examples/sim/abstract_transactions_wb.py +++ b/examples/sim/abstract_transactions_wb.py @@ -5,6 +5,7 @@ from migen.bus.transactions import * from migen.bus import wishbone from migen.sim.generic import run_simulation + # Our bus master. # Python generators let us program bus transactions in an elegant sequential style. def my_generator(): @@ -27,6 +28,7 @@ def my_generator(): for delay in range(prng.randrange(0, 3)): yield None + # Our bus slave. class MyModelWB(wishbone.TargetModel): def __init__(self): @@ -39,6 +41,7 @@ class MyModelWB(wishbone.TargetModel): # Simulate variable latency. return self.prng.randrange(0, 2) + class TB(Module): def __init__(self): # The "wishbone.Initiator" library component runs our generator diff --git a/examples/sim/basic1.py b/examples/sim/basic1.py index 0726f8e5..77b35310 100644 --- a/examples/sim/basic1.py +++ b/examples/sim/basic1.py @@ -1,6 +1,7 @@ from migen.fhdl.std import * from migen.sim.generic import run_simulation + # Our simple counter, which increments at every cycle # and prints its current value in simulation. class Counter(Module): diff --git a/examples/sim/basic2.py b/examples/sim/basic2.py index fd4f8693..958e828a 100644 --- a/examples/sim/basic2.py +++ b/examples/sim/basic2.py @@ -1,6 +1,7 @@ from migen.fhdl.std import * from migen.sim.generic import run_simulation + # A slightly more elaborate counter. # Has a clock enable (CE) signal, counts on more bits # and resets with a negative number. diff --git a/examples/sim/dataflow.py b/examples/sim/dataflow.py index ea606736..1a5f1000 100644 --- a/examples/sim/dataflow.py +++ b/examples/sim/dataflow.py @@ -5,27 +5,32 @@ from migen.flow.network import * from migen.actorlib.sim import * from migen.sim.generic import run_simulation + def source_gen(): for i in range(10): print("Sending: " + str(i)) yield Token("source", {"value": i}) + class SimSource(SimActor): def __init__(self): self.source = Source([("value", 32)]) SimActor.__init__(self, source_gen()) + def sink_gen(): while True: t = Token("sink") yield t print("Received: " + str(t.value["value"])) + class SimSink(SimActor): def __init__(self): self.sink = Sink([("value", 32)]) SimActor.__init__(self, sink_gen()) + class TB(Module): def __init__(self): self.source = SimSource() diff --git a/examples/sim/fir.py b/examples/sim/fir.py index 4b64d427..e31cc144 100644 --- a/examples/sim/fir.py +++ b/examples/sim/fir.py @@ -7,6 +7,7 @@ from migen.fhdl import verilog from migen.genlib.misc import optree from migen.sim.generic import run_simulation + # A synthesizable FIR filter. class FIR(Module): def __init__(self, coef, wsize=16): @@ -29,6 +30,7 @@ class FIR(Module): self.sync += sum_full.eq(optree("+", muls)) self.comb += self.o.eq(sum_full[self.wsize-1:]) + # A test bench for our FIR filter. # Generates a sine wave at the input and records the output. class TB(Module): diff --git a/examples/sim/memory.py b/examples/sim/memory.py index a7321c36..db9bde57 100644 --- a/examples/sim/memory.py +++ b/examples/sim/memory.py @@ -1,6 +1,7 @@ from migen.fhdl.std import * from migen.sim.generic import run_simulation + class Mem(Module): def __init__(self): # Initialize the beginning of the memory with integers diff --git a/mibuild/altera/platform.py b/mibuild/altera/platform.py index 1e2d6453..7023581f 100644 --- a/mibuild/altera/platform.py +++ b/mibuild/altera/platform.py @@ -1,6 +1,7 @@ from mibuild.generic_platform import GenericPlatform from mibuild.altera import common, quartus + class AlteraPlatform(GenericPlatform): bitstream_ext = ".sof" diff --git a/mibuild/altera/programmer.py b/mibuild/altera/programmer.py index a60ec091..13af0f49 100644 --- a/mibuild/altera/programmer.py +++ b/mibuild/altera/programmer.py @@ -2,6 +2,7 @@ import subprocess from mibuild.generic_programmer import GenericProgrammer + class USBBlaster(GenericProgrammer): needs_bitreverse = False diff --git a/mibuild/altera/quartus.py b/mibuild/altera/quartus.py index e28cbd8c..06f17528 100644 --- a/mibuild/altera/quartus.py +++ b/mibuild/altera/quartus.py @@ -9,6 +9,7 @@ from mibuild.generic_platform import * from mibuild import tools from mibuild.xilinx import common + def _format_constraint(c): if isinstance(c, Pins): return "set_location_assignment PIN_" + c.identifiers[0] @@ -17,6 +18,7 @@ def _format_constraint(c): elif isinstance(c, Misc): return c.misc + def _format_qsf(signame, pin, others, resname): fmt_c = [_format_constraint(c) for c in ([Pins(pin)] + others)] fmt_r = resname[0] + ":" + str(resname[1]) @@ -27,6 +29,7 @@ def _format_qsf(signame, pin, others, resname): r += c + " -to " + signame + " # " + fmt_r + "\n" return r + def _build_qsf(named_sc, named_pc): r = "" for sig, pins, others, resname in named_sc: @@ -40,6 +43,7 @@ def _build_qsf(named_sc, named_pc): r += "set_global_assignment -name top_level_entity top\n" return r + def _build_files(device, sources, vincpaths, named_sc, named_pc, build_name): qsf_contents = "" for filename, language in sources: @@ -55,6 +59,7 @@ def _build_files(device, sources, vincpaths, named_sc, named_pc, build_name): qsf_contents += "set_global_assignment -name DEVICE " + device tools.write_to_file(build_name + ".qsf", qsf_contents) + def _run_quartus(build_name, quartus_path): build_script_contents = """# Autogenerated by mibuild @@ -71,6 +76,7 @@ quartus_sta {build_name} -c {build_name} if r != 0: raise OSError("Subprocess failed") + class AlteraQuartusToolchain: def build(self, platform, fragment, build_dir="build", build_name="top", quartus_path="/opt/Altera", run=True): diff --git a/mibuild/generic_platform.py b/mibuild/generic_platform.py index 0a6b65e8..25f4f150 100644 --- a/mibuild/generic_platform.py +++ b/mibuild/generic_platform.py @@ -9,42 +9,51 @@ from migen.util.misc import autotype from mibuild import tools + class ConstraintError(Exception): pass + class Pins: def __init__(self, *identifiers): self.identifiers = [] for i in identifiers: self.identifiers += i.split() + class IOStandard: def __init__(self, name): self.name = name + class Drive: def __init__(self, strength): self.strength = strength + class Misc: def __init__(self, misc): self.misc = misc + class Subsignal: def __init__(self, name, *constraints): self.name = name self.constraints = list(constraints) + class PlatformInfo: def __init__(self, info): self.info = info + def _lookup(description, name, number): for resource in description: if resource[0] == name and (number is None or resource[1] == number): return resource raise ConstraintError("Resource not found: " + name + ":" + str(number)) + def _resource_type(resource): t = None for element in resource[2:]: @@ -63,6 +72,7 @@ def _resource_type(resource): t.append((element.name, n_bits)) return t + class ConnectorManager: def __init__(self, connectors): self.connector_table = dict() @@ -95,6 +105,7 @@ class ConnectorManager: r.append(identifier) return r + def _separate_pins(constraints): pins = None others = [] @@ -106,6 +117,7 @@ def _separate_pins(constraints): others.append(c) return pins, others + class ConstraintManager: def __init__(self, io, connectors): self.available = list(io) @@ -177,6 +189,7 @@ class ConstraintManager: def get_platform_commands(self): return self.platform_commands + class GenericPlatform: def __init__(self, device, io, connectors=[], name=None): self.device = device diff --git a/mibuild/generic_programmer.py b/mibuild/generic_programmer.py index 9285112a..82a1ebe0 100644 --- a/mibuild/generic_programmer.py +++ b/mibuild/generic_programmer.py @@ -1,5 +1,6 @@ import os + class GenericProgrammer: def __init__(self, flash_proxy_basename=None): self.flash_proxy_basename = flash_proxy_basename diff --git a/mibuild/lattice/common.py b/mibuild/lattice/common.py index 39bf3c63..090d3fc0 100644 --- a/mibuild/lattice/common.py +++ b/mibuild/lattice/common.py @@ -3,6 +3,7 @@ from migen.genlib.io import * from migen.genlib.resetsync import AsyncResetSynchronizer + class LatticeAsyncResetSynchronizerImpl(Module): def __init__(self, cd, async_reset): rst1 = Signal() @@ -13,11 +14,13 @@ class LatticeAsyncResetSynchronizerImpl(Module): i_CK=cd.clk, o_Q=cd.rst) ] + class LatticeAsyncResetSynchronizer: @staticmethod def lower(dr): return LatticeAsyncResetSynchronizerImpl(dr.cd, dr.async_reset) + class LatticeDDROutputImpl(Module): def __init__(self, i1, i2, o, clk): self.specials += Instance("ODDRXD1", @@ -26,6 +29,7 @@ class LatticeDDROutputImpl(Module): i_DA=i1, i_DB=i2, o_Q=o, ) + class LatticeDDROutput: @staticmethod def lower(dr): diff --git a/mibuild/lattice/diamond.py b/mibuild/lattice/diamond.py index 2217ef5e..1d82634b 100644 --- a/mibuild/lattice/diamond.py +++ b/mibuild/lattice/diamond.py @@ -9,6 +9,7 @@ from mibuild.generic_platform import * from mibuild import tools from mibuild.lattice import common + def _format_constraint(c): if isinstance(c, Pins): return ("LOCATE COMP ", " SITE " + "\"" + c.identifiers[0] + "\"") @@ -17,6 +18,7 @@ def _format_constraint(c): elif isinstance(c, Misc): return c.misc + def _format_lpf(signame, pin, others, resname): fmt_c = [_format_constraint(c) for c in ([Pins(pin)] + others)] r = "" @@ -24,6 +26,7 @@ def _format_lpf(signame, pin, others, resname): r += pre + "\""+ signame +"\"" + suf + ";\n" return r + def _build_lpf(named_sc, named_pc): r = "BLOCK RESETPATHS;\n" r += "BLOCK ASYNCPATHS;\n" @@ -37,6 +40,7 @@ def _build_lpf(named_sc, named_pc): r += "\n" + "\n\n".join(named_pc) return r + def _build_files(device, sources, vincpaths, build_name): tcl = [] tcl.append("prj_project new -name \"%s\" -impl \"implementation\" -dev %s -synthesis \"synplify\"" %(build_name, device)) @@ -51,6 +55,7 @@ def _build_files(device, sources, vincpaths, build_name): tcl.append("prj_run Export -impl implementation -task Bitgen") tools.write_to_file(build_name + ".tcl", "\n".join(tcl)) + def _run_diamond(build_name, source, ver=None): if sys.platform == "win32" or sys.platform == "cygwin": build_script_contents = "REM Autogenerated by mibuild\n" @@ -65,6 +70,7 @@ def _run_diamond(build_name, source, ver=None): if r != 0: raise OSError("Subprocess failed") + class LatticeDiamondToolchain: def build(self, platform, fragment, build_dir="build", build_name="top", diamond_path="/opt/Diamond", run=True): diff --git a/mibuild/lattice/platform.py b/mibuild/lattice/platform.py index 88961512..08be54e9 100644 --- a/mibuild/lattice/platform.py +++ b/mibuild/lattice/platform.py @@ -1,6 +1,7 @@ from mibuild.generic_platform import GenericPlatform from mibuild.lattice import common, diamond + class LatticePlatform(GenericPlatform): bitstream_ext = ".bit" diff --git a/mibuild/lattice/programmer.py b/mibuild/lattice/programmer.py index ea6d119a..6b3e9a40 100644 --- a/mibuild/lattice/programmer.py +++ b/mibuild/lattice/programmer.py @@ -41,6 +41,7 @@ _xcf_template = """ """ + class LatticeProgrammer(GenericProgrammer): needs_bitreverse = False diff --git a/mibuild/platforms/apf27.py b/mibuild/platforms/apf27.py index 383e8daa..ee21f792 100644 --- a/mibuild/platforms/apf27.py +++ b/mibuild/platforms/apf27.py @@ -140,6 +140,7 @@ _connectors = [ "None") # 116 USBH2_CLK USB_HOST2 +2V5 PA0 ] + class Platform(XilinxPlatform): default_clk_name = "clk0" default_clk_period = 10 diff --git a/mibuild/platforms/apf51.py b/mibuild/platforms/apf51.py index 26823882..4cfaa9d8 100644 --- a/mibuild/platforms/apf51.py +++ b/mibuild/platforms/apf51.py @@ -167,6 +167,7 @@ _connectors = [ "None") # 140 FPGA_BANK3_POWER ] + class Platform(XilinxPlatform): default_clk_name = "clk3" default_clk_period = 10.526 diff --git a/mibuild/platforms/de0nano.py b/mibuild/platforms/de0nano.py index f4d065a8..eec8fd28 100644 --- a/mibuild/platforms/de0nano.py +++ b/mibuild/platforms/de0nano.py @@ -90,6 +90,7 @@ _io = [ ), ] + class Platform(AlteraPlatform): default_clk_name = "clk50" default_clk_period = 20 diff --git a/mibuild/platforms/kc705.py b/mibuild/platforms/kc705.py index 6f3cccb7..16e302b1 100644 --- a/mibuild/platforms/kc705.py +++ b/mibuild/platforms/kc705.py @@ -375,6 +375,7 @@ _connectors = [ ) ] + class Platform(XilinxPlatform): identifier = 0x4B37 default_clk_name = "clk156" diff --git a/mibuild/platforms/m1.py b/mibuild/platforms/m1.py index 84a70d2e..93e213b2 100644 --- a/mibuild/platforms/m1.py +++ b/mibuild/platforms/m1.py @@ -117,6 +117,7 @@ _io = [ ) ] + class Platform(XilinxPlatform): identifier = 0x4D31 default_clk_name = "clk50" diff --git a/mibuild/platforms/minispartan6.py b/mibuild/platforms/minispartan6.py index 1db3d4db..11ec3235 100644 --- a/mibuild/platforms/minispartan6.py +++ b/mibuild/platforms/minispartan6.py @@ -107,6 +107,7 @@ _connectors = [ ("F", "E2 E1 E4 F4 F5 G3 F3 G1 H3 H1 H2 J1") ] + class Platform(XilinxPlatform): default_clk_name = "clk32" default_clk_period = 31.25 diff --git a/mibuild/platforms/mixxeo.py b/mibuild/platforms/mixxeo.py index 217baf18..69096e54 100644 --- a/mibuild/platforms/mixxeo.py +++ b/mibuild/platforms/mixxeo.py @@ -153,6 +153,7 @@ _io = [ ), ] + class Platform(XilinxPlatform): identifier = 0x4D58 default_clk_name = "clk50" diff --git a/mibuild/platforms/ml605.py b/mibuild/platforms/ml605.py index ccec0eed..26ac49fc 100644 --- a/mibuild/platforms/ml605.py +++ b/mibuild/platforms/ml605.py @@ -50,6 +50,7 @@ _io = [ ) ] + class Platform(XilinxPlatform): default_clk_name = "clk200" default_clk_period = 5 diff --git a/mibuild/platforms/papilio_pro.py b/mibuild/platforms/papilio_pro.py index 741d7b0a..5d35c7a3 100644 --- a/mibuild/platforms/papilio_pro.py +++ b/mibuild/platforms/papilio_pro.py @@ -48,6 +48,7 @@ _connectors = [ ("C", "P114 P115 P116 P117 P118 P119 P120 P121 P123 P124 P126 P127 P131 P132 P133 P134") ] + class Platform(XilinxPlatform): identifier = 0x5050 default_clk_name = "clk32" diff --git a/mibuild/platforms/pipistrello.py b/mibuild/platforms/pipistrello.py index 2b2c9cc6..5f5c591d 100644 --- a/mibuild/platforms/pipistrello.py +++ b/mibuild/platforms/pipistrello.py @@ -123,6 +123,7 @@ _connectors = [ ("C", "F17 F16 E16 G16 F15 G14 F14 H14 H13 J13 G13 H12 K14 K13 K12 L12"), ] + class Platform(XilinxPlatform): identifier = 0x5049 default_clk_name = "clk50" diff --git a/mibuild/platforms/rhino.py b/mibuild/platforms/rhino.py index feb4fa4a..ab03b9a5 100644 --- a/mibuild/platforms/rhino.py +++ b/mibuild/platforms/rhino.py @@ -132,6 +132,7 @@ _io = [ ) ] + class Platform(XilinxPlatform): default_clk_name = "clk100" default_clk_period = 10 diff --git a/mibuild/platforms/roach.py b/mibuild/platforms/roach.py index b2ca92f4..66f81337 100644 --- a/mibuild/platforms/roach.py +++ b/mibuild/platforms/roach.py @@ -28,6 +28,7 @@ _io = [ ), ] + class Platform(XilinxPlatform): def __init__(self): XilinxPlatform.__init__(self, "xc5vsx95t-ff1136-1", _io) diff --git a/mibuild/platforms/sim.py b/mibuild/platforms/sim.py index 81d5106f..d072c17a 100644 --- a/mibuild/platforms/sim.py +++ b/mibuild/platforms/sim.py @@ -1,6 +1,7 @@ from mibuild.generic_platform import * from mibuild.sim import SimPlatform + class SimPins(Pins): def __init__(self, n): Pins.__init__(self, "s "*n) @@ -31,6 +32,7 @@ _io = [ ), ] + class Platform(SimPlatform): is_sim = True default_clk_name = "sys_clk" diff --git a/mibuild/platforms/versa.py b/mibuild/platforms/versa.py index 83b41a6d..4a0d2794 100644 --- a/mibuild/platforms/versa.py +++ b/mibuild/platforms/versa.py @@ -73,6 +73,7 @@ _io = [ ), ] + class Platform(LatticePlatform): default_clk_name = "clk100" default_clk_period = 10 diff --git a/mibuild/platforms/ztex_115d.py b/mibuild/platforms/ztex_115d.py index 1b8f40df..7ca6afde 100644 --- a/mibuild/platforms/ztex_115d.py +++ b/mibuild/platforms/ztex_115d.py @@ -80,6 +80,7 @@ _io = [ ] + class Platform(XilinxPlatform): default_clk_name = "clk_if" default_clk_period = 20 diff --git a/mibuild/sim/platform.py b/mibuild/sim/platform.py index 830037bc..c36cef04 100644 --- a/mibuild/sim/platform.py +++ b/mibuild/sim/platform.py @@ -1,6 +1,7 @@ from mibuild.generic_platform import GenericPlatform from mibuild.sim import common, verilator + class SimPlatform(GenericPlatform): def __init__(self, *args, toolchain="verilator", **kwargs): GenericPlatform.__init__(self, *args, **kwargs) diff --git a/mibuild/sim/verilator.py b/mibuild/sim/verilator.py index 11b1b503..e0d7ff33 100644 --- a/mibuild/sim/verilator.py +++ b/mibuild/sim/verilator.py @@ -10,6 +10,7 @@ from mibuild.generic_platform import * from mibuild import tools from mibuild.sim import common + def _build_tb(platform, vns, serial, template): def io_name(ressource, subsignal=None): @@ -82,6 +83,7 @@ def _build_tb(platform, vns, serial, template): f.close() tools.write_to_file("dut_tb.cpp", content) + def _build_sim(platform, vns, build_name, include_paths, sim_path, serial, verbose): include = "" for path in include_paths: @@ -106,6 +108,7 @@ make -j -C obj_dir/ -f Vdut.mk Vdut if r != 0: raise OSError("Subprocess failed") + def _run_sim(build_name): run_script_contents = """obj_dir/Vdut """ @@ -115,6 +118,7 @@ def _run_sim(build_name): if r != 0: raise OSError("Subprocess failed") + class SimVerilatorToolchain: # XXX fir sim_path def build(self, platform, fragment, build_dir="build", build_name="top", diff --git a/mibuild/tools.py b/mibuild/tools.py index b330d933..402db163 100644 --- a/mibuild/tools.py +++ b/mibuild/tools.py @@ -1,12 +1,14 @@ import os, struct from distutils.version import StrictVersion + def mkdir_noerror(d): try: os.mkdir(d) except OSError: pass + def language_by_filename(name): extension = name.rsplit(".")[-1] if extension in ["v", "vh", "vo"]: @@ -15,6 +17,7 @@ def language_by_filename(name): return "vhdl" return None + def write_to_file(filename, contents, force_unix=False): newline = None if force_unix: @@ -22,9 +25,11 @@ def write_to_file(filename, contents, force_unix=False): with open(filename, "w", newline=newline) as f: f.write(contents) + def arch_bits(): return struct.calcsize("P")*8 + def versions(path): for n in os.listdir(path): full = os.path.join(path, n) diff --git a/mibuild/xilinx/common.py b/mibuild/xilinx/common.py index 604c6451..8182ab23 100644 --- a/mibuild/xilinx/common.py +++ b/mibuild/xilinx/common.py @@ -8,6 +8,7 @@ from migen.genlib.resetsync import AsyncResetSynchronizer from migen.genlib.io import * from mibuild import tools + def settings(path, ver=None, sub=None): vers = list(tools.versions(path)) if ver is None: @@ -31,26 +32,31 @@ def settings(path, ver=None, sub=None): raise OSError("no settings file found") + class XilinxNoRetimingImpl(Module): def __init__(self, reg): self.specials += SynthesisDirective("attribute register_balancing of {r} is no", r=reg) + class XilinxNoRetiming: @staticmethod def lower(dr): return XilinxNoRetimingImpl(dr.reg) + class XilinxMultiRegImpl(MultiRegImpl): def __init__(self, *args, **kwargs): MultiRegImpl.__init__(self, *args, **kwargs) self.specials += [SynthesisDirective("attribute shreg_extract of {r} is no", r=r) for r in self.regs] + class XilinxMultiReg: @staticmethod def lower(dr): return XilinxMultiRegImpl(dr.i, dr.o, dr.odomain, dr.n) + class XilinxAsyncResetSynchronizerImpl(Module): def __init__(self, cd, async_reset): rst1 = Signal() @@ -61,29 +67,35 @@ class XilinxAsyncResetSynchronizerImpl(Module): i_CE=1, i_C=cd.clk, o_Q=cd.rst) ] + class XilinxAsyncResetSynchronizer: @staticmethod def lower(dr): return XilinxAsyncResetSynchronizerImpl(dr.cd, dr.async_reset) + class XilinxDifferentialInputImpl(Module): def __init__(self, i_p, i_n, o): self.specials += Instance("IBUFDS", i_I=i_p, i_IB=i_n, o_O=o) + class XilinxDifferentialInput: @staticmethod def lower(dr): return XilinxDifferentialInputImpl(dr.i_p, dr.i_n, dr.o) + class XilinxDifferentialOutputImpl(Module): def __init__(self, i, o_p, o_n): self.specials += Instance("OBUFDS", i_I=i, o_O=o_p, o_OB=o_n) + class XilinxDifferentialOutput: @staticmethod def lower(dr): return XilinxDifferentialOutputImpl(dr.i, dr.o_p, dr.o_n) + class XilinxDDROutputImpl(Module): def __init__(self, i1, i2, o, clk): self.specials += Instance("ODDR", @@ -92,6 +104,7 @@ class XilinxDDROutputImpl(Module): i_D1=i1, i_D2=i2, o_Q=o, ) + class XilinxDDROutput: @staticmethod def lower(dr): diff --git a/mibuild/xilinx/ise.py b/mibuild/xilinx/ise.py index c578bab8..48a32b77 100644 --- a/mibuild/xilinx/ise.py +++ b/mibuild/xilinx/ise.py @@ -7,6 +7,7 @@ from mibuild.generic_platform import * from mibuild import tools from mibuild.xilinx import common + def _format_constraint(c): if isinstance(c, Pins): return "LOC=" + c.identifiers[0] @@ -17,6 +18,7 @@ def _format_constraint(c): elif isinstance(c, Misc): return c.misc + def _format_ucf(signame, pin, others, resname): fmt_c = [] for c in [Pins(pin)] + others: @@ -28,6 +30,7 @@ def _format_ucf(signame, pin, others, resname): fmt_r += "." + resname[2] return "NET \"" + signame + "\" " + " | ".join(fmt_c) + "; # " + fmt_r + "\n" + def _build_ucf(named_sc, named_pc): r = "" for sig, pins, others, resname in named_sc: @@ -40,6 +43,7 @@ def _build_ucf(named_sc, named_pc): r += "\n" + "\n\n".join(named_pc) return r + def _build_xst_files(device, sources, vincpaths, build_name, xst_opt): prj_contents = "" for filename, language in sources: @@ -57,6 +61,7 @@ def _build_xst_files(device, sources, vincpaths, build_name, xst_opt): xst_contents += "-vlgincdir " + path + "\n" tools.write_to_file(build_name + ".xst", xst_contents) + def _run_yosys(device, sources, vincpaths, build_name): ys_contents = "" incflags = "" @@ -87,6 +92,7 @@ synth_xilinx -arch {arch} -top top -edif {build_name}.edif""".format(arch=arch, if r != 0: raise OSError("Subprocess failed") + def _run_ise(build_name, ise_path, source, mode, ngdbuild_opt, bitgen_opt, ise_commands, map_opt, par_opt, ver=None): if sys.platform == "win32" or sys.platform == "cygwin": @@ -120,6 +126,7 @@ bitgen {bitgen_opt} {build_name}.ncd {build_name}.bit if r != 0: raise OSError("Subprocess failed") + class XilinxISEToolchain: def __init__(self): self.xst_opt = """-ifmt MIXED diff --git a/mibuild/xilinx/platform.py b/mibuild/xilinx/platform.py index 142c79f0..cf202b17 100644 --- a/mibuild/xilinx/platform.py +++ b/mibuild/xilinx/platform.py @@ -1,6 +1,7 @@ from mibuild.generic_platform import GenericPlatform from mibuild.xilinx import common, vivado, ise + class XilinxPlatform(GenericPlatform): bitstream_ext = ".bit" diff --git a/mibuild/xilinx/programmer.py b/mibuild/xilinx/programmer.py index ae26d42b..ed24e9ca 100644 --- a/mibuild/xilinx/programmer.py +++ b/mibuild/xilinx/programmer.py @@ -3,11 +3,13 @@ import sys, subprocess from mibuild.generic_programmer import GenericProgrammer from mibuild.xilinx import common + def _run_urjtag(cmds): with subprocess.Popen("jtag", stdin=subprocess.PIPE) as process: process.stdin.write(cmds.encode("ASCII")) process.communicate() + class UrJTAG(GenericProgrammer): needs_bitreverse = True @@ -32,6 +34,7 @@ flashmem "{address}" "{data_file}" noverify """.format(flash_proxy=flash_proxy, address=address, data_file=data_file) _run_urjtag(cmds) + class XC3SProg(GenericProgrammer): needs_bitreverse = False @@ -47,6 +50,7 @@ class XC3SProg(GenericProgrammer): subprocess.call(["xc3sprog", "-v", "-c", self.cable, "-I"+flash_proxy, "{}:w:0x{:x}:BIN".format(data_file, address)]) + class FpgaProg(GenericProgrammer): needs_bitreverse = False @@ -63,11 +67,13 @@ class FpgaProg(GenericProgrammer): subprocess.call(["fpgaprog", "-v", "-sa", "-r", "-b", flash_proxy, "-f", data_file]) + def _run_impact(cmds): with subprocess.Popen("impact -batch", stdin=subprocess.PIPE) as process: process.stdin.write(cmds.encode("ASCII")) process.communicate() + class iMPACT(GenericProgrammer): needs_bitreverse = False @@ -80,6 +86,7 @@ quit """.format(bitstream=bitstream_file) _run_impact(cmds) + def _run_vivado(path, ver, cmds): if sys.platform == "win32" or sys.platform == "cygwin": vivado_cmd = "vivado -mode tcl" @@ -90,6 +97,7 @@ def _run_vivado(path, ver, cmds): process.stdin.write(cmds.encode("ASCII")) process.communicate() + class VivadoProgrammer(GenericProgrammer): needs_bitreverse = False def __init__(self, vivado_path="/opt/Xilinx/Vivado", vivado_ver=None): diff --git a/mibuild/xilinx/vivado.py b/mibuild/xilinx/vivado.py index 6077b2f8..6d11166d 100644 --- a/mibuild/xilinx/vivado.py +++ b/mibuild/xilinx/vivado.py @@ -10,6 +10,7 @@ from mibuild.generic_platform import * from mibuild import tools from mibuild.xilinx import common + def _format_constraint(c): if isinstance(c, Pins): return "set_property LOC " + c.identifiers[0] @@ -22,6 +23,7 @@ def _format_constraint(c): else: raise ValueError("unknown constraint %s" % c) + def _format_xdc(signame, resname, *constraints): fmt_c = [_format_constraint(c) for c in constraints] fmt_r = resname[0] + ":" + str(resname[1]) @@ -32,6 +34,7 @@ def _format_xdc(signame, resname, *constraints): r += c + " [get_ports " + signame + "]\n" return r + def _build_xdc(named_sc, named_pc): r = "" for sig, pins, others, resname in named_sc: @@ -46,6 +49,7 @@ def _build_xdc(named_sc, named_pc): r += "\n" + "\n\n".join(named_pc) return r + def _run_vivado(build_name, vivado_path, source, ver=None): if sys.platform == "win32" or sys.platform == "cygwin": build_script_contents = "REM Autogenerated by mibuild\n" @@ -65,6 +69,7 @@ def _run_vivado(build_name, vivado_path, source, ver=None): if r != 0: raise OSError("Subprocess failed") + class XilinxVivadoToolchain: def __init__(self): self.bitstream_commands = [] diff --git a/migen/actorlib/dma_wishbone.py b/migen/actorlib/dma_wishbone.py index b9076732..4f6908bb 100644 --- a/migen/actorlib/dma_wishbone.py +++ b/migen/actorlib/dma_wishbone.py @@ -2,6 +2,7 @@ from migen.fhdl.std import * from migen.bus import wishbone from migen.flow.actor import * + class Reader(Module): def __init__(self): self.bus = wishbone.Interface() @@ -34,6 +35,7 @@ class Reader(Module): ) ] + class Writer(Module): def __init__(self): self.bus = wishbone.Interface() diff --git a/migen/actorlib/fifo.py b/migen/actorlib/fifo.py index 7029269e..072e99c7 100644 --- a/migen/actorlib/fifo.py +++ b/migen/actorlib/fifo.py @@ -2,6 +2,7 @@ from migen.fhdl.std import * from migen.flow.actor import * from migen.genlib import fifo + class _FIFOActor(Module): def __init__(self, fifo_class, layout, depth): self.sink = Sink(layout) @@ -42,6 +43,7 @@ class _FIFOActor(Module): self.source.eop.eq(self.fifo.dout.eop) ] + class SyncFIFO(_FIFOActor): def __init__(self, layout, depth, buffered=False): _FIFOActor.__init__( @@ -49,6 +51,7 @@ class SyncFIFO(_FIFOActor): fifo.SyncFIFOBuffered if buffered else fifo.SyncFIFO, layout, depth) + class AsyncFIFO(_FIFOActor): def __init__(self, layout, depth): _FIFOActor.__init__(self, fifo.AsyncFIFO, layout, depth) diff --git a/migen/actorlib/misc.py b/migen/actorlib/misc.py index 0800a421..0779957c 100644 --- a/migen/actorlib/misc.py +++ b/migen/actorlib/misc.py @@ -3,6 +3,7 @@ from migen.genlib.record import * from migen.genlib.fsm import * from migen.flow.actor import * + # Generates integers from start to maximum-1 class IntSequence(Module): def __init__(self, nbits, offsetbits=0, step=1): diff --git a/migen/actorlib/sim.py b/migen/actorlib/sim.py index 87efb751..9c7775eb 100644 --- a/migen/actorlib/sim.py +++ b/migen/actorlib/sim.py @@ -3,6 +3,7 @@ from migen.flow.actor import * from migen.flow.transactions import * from migen.util.misc import xdir + def _sim_multiread(sim, obj): if isinstance(obj, Signal): return sim.rd(obj) @@ -14,6 +15,7 @@ def _sim_multiread(sim, obj): r[k] = rd return r + def _sim_multiwrite(sim, obj, value): if isinstance(obj, Signal): sim.wr(obj, value) @@ -21,6 +23,7 @@ def _sim_multiwrite(sim, obj, value): for k, v in value.items(): _sim_multiwrite(sim, getattr(obj, k), v) + # Generators yield None or a tuple of Tokens. # Tokens for Sink endpoints are pulled and the "value" field filled in. # Tokens for Source endpoints are pushed according to their "value" field. @@ -91,6 +94,7 @@ class TokenExchanger(Module): self._update_control_signals(selfp) do_simulation.passive = True + class SimActor(Module): def __init__(self, generator): self.busy = Signal() @@ -100,6 +104,7 @@ class SimActor(Module): selfp.busy = self.token_exchanger.busy do_simulation.passive = True + def _dumper_gen(prefix): while True: t = Token("result") @@ -110,6 +115,7 @@ def _dumper_gen(prefix): s = str(list(t.value.values())[0]) print(prefix + s) + class Dumper(SimActor): def __init__(self, layout, prefix=""): self.result = Sink(layout) diff --git a/migen/actorlib/spi.py b/migen/actorlib/spi.py index 175312df..76d759a0 100644 --- a/migen/actorlib/spi.py +++ b/migen/actorlib/spi.py @@ -7,6 +7,7 @@ from migen.flow.network import * from migen.flow import plumbing from migen.actorlib import misc + # layout is a list of tuples, either: # - (name, nbits, [reset value], [alignment bits]) # - (name, sublayout) @@ -22,6 +23,7 @@ def _convert_layout(layout): (MODE_EXTERNAL, MODE_SINGLE_SHOT, MODE_CONTINUOUS) = range(3) + class SingleGenerator(Module, AutoCSR): def __init__(self, layout, mode): self.source = Source(_convert_layout(layout)) @@ -68,6 +70,7 @@ class SingleGenerator(Module, AutoCSR): self.sync += If(self.source.ack | ~self.source.stb, getattr(target, name).eq(reg.storage)) + class Collector(Module, AutoCSR): def __init__(self, layout, depth=1024): self.sink = Sink(layout) @@ -108,6 +111,7 @@ class Collector(Module, AutoCSR): self._rd.status.eq(rp.dat_r) ] + class _DMAController(Module): def __init__(self, bus_accessor, bus_aw, bus_dw, mode, base_reset=0, length_reset=0): self.alignment_bits = bits_for(bus_dw//8) - 1 @@ -126,6 +130,7 @@ class _DMAController(Module): def get_csrs(self): return self.generator.get_csrs() + [self.r_busy] + class DMAReadController(_DMAController): def __init__(self, bus_accessor, *args, **kwargs): bus_aw = flen(bus_accessor.address.a) @@ -145,6 +150,7 @@ class DMAReadController(_DMAController): self.busy = comp_actor.busy self.comb += self.r_busy.status.eq(self.busy) + class DMAWriteController(_DMAController): def __init__(self, bus_accessor, *args, ack_when_inactive=False, **kwargs): bus_aw = flen(bus_accessor.address_data.a) diff --git a/migen/actorlib/structuring.py b/migen/actorlib/structuring.py index 6a74b18e..476bdf72 100644 --- a/migen/actorlib/structuring.py +++ b/migen/actorlib/structuring.py @@ -4,12 +4,14 @@ from migen.fhdl.std import * from migen.genlib.record import * from migen.flow.actor import * + def _rawbits_layout(l): if isinstance(l, int): return [("rawbits", l)] else: return l + class Cast(CombinatorialActor): def __init__(self, layout_from, layout_to, reverse_from=False, reverse_to=False): self.sink = Sink(_rawbits_layout(layout_from)) @@ -28,9 +30,11 @@ class Cast(CombinatorialActor): raise TypeError self.comb += Cat(*sigs_to).eq(Cat(*sigs_from)) + def pack_layout(l, n): return [("chunk"+str(i), l) for i in range(n)] + class Unpack(Module): def __init__(self, n, layout_to, reverse=False): self.source = source = Source(layout_to) @@ -77,6 +81,7 @@ class Unpack(Module): source.eop.eq(sink.eop & last) ] + class Pack(Module): def __init__(self, layout_from, n, reverse=False): self.sink = sink = Sink(layout_from) @@ -136,6 +141,7 @@ class Pack(Module): ) ] + class Chunkerize(CombinatorialActor): def __init__(self, layout_from, layout_to, n, reverse=False): self.sink = Sink(layout_from) @@ -161,6 +167,7 @@ class Chunkerize(CombinatorialActor): dst = getattr(self.source, f[0]) self.comb += dst.eq(src) + class Unchunkerize(CombinatorialActor): def __init__(self, layout_from, n, layout_to, reverse=False): if isinstance(layout_from, EndpointDescription): @@ -188,6 +195,7 @@ class Unchunkerize(CombinatorialActor): dst = getattr(self.source, f[0]) self.comb += dst.eq(src) + class Converter(Module): def __init__(self, layout_from, layout_to, reverse=False): self.sink = Sink(layout_from) @@ -231,6 +239,7 @@ class Converter(Module): else: self.comb += Record.connect(self.sink, self.source) + class Pipeline(Module): def __init__(self, *modules): self.busy = Signal() diff --git a/migen/bank/bank.py b/migen/bank/bank.py index b27d8cf5..d8622011 100644 --- a/migen/bank/bank.py +++ b/migen/bank/bank.py @@ -1,6 +1,7 @@ from migen.fhdl.std import Module, bits_for from migen.bank.description import CSR + class GenericBank(Module): def __init__(self, description, busword): # Turn description into simple CSRs and claim ownership of compound CSR modules @@ -14,6 +15,7 @@ class GenericBank(Module): self.submodules += c self.decode_bits = bits_for(len(self.simple_csrs)-1) + def get_offset(description, name, busword): offset = 0 for c in description: diff --git a/migen/bank/csrgen.py b/migen/bank/csrgen.py index 67a337e1..6ef6f41d 100644 --- a/migen/bank/csrgen.py +++ b/migen/bank/csrgen.py @@ -3,6 +3,7 @@ from migen.fhdl.std import * from migen.bus import csr from migen.bank.bank import GenericBank + class Bank(GenericBank): def __init__(self, description, address=0, bus=None): if bus is None: @@ -30,6 +31,7 @@ class Bank(GenericBank): If(sel, Case(self.bus.adr[:self.decode_bits], brcases)) ] + # address_map(name, memory) returns the CSR offset at which to map # the CSR object (register bank or memory). # If memory=None, the object is the register bank of object source.name. diff --git a/migen/bank/description.py b/migen/bank/description.py index 1f9fe38d..f6b267be 100644 --- a/migen/bank/description.py +++ b/migen/bank/description.py @@ -2,6 +2,7 @@ from migen.util.misc import xdir from migen.fhdl.std import * from migen.fhdl.tracer import get_obj_var_name + class _CSRBase(HUID): def __init__(self, size, name): HUID.__init__(self) @@ -10,6 +11,7 @@ class _CSRBase(HUID): raise ValueError("Cannot extract CSR name from code, need to specify.") self.size = size + class CSR(_CSRBase): def __init__(self, size=1, name=None): _CSRBase.__init__(self, size, name) @@ -17,6 +19,7 @@ class CSR(_CSRBase): self.r = Signal(self.size, name=self.name + "_r") self.w = Signal(self.size, name=self.name + "_w") + class _CompoundCSR(_CSRBase, Module): def __init__(self, size, name): _CSRBase.__init__(self, size, name) @@ -30,6 +33,7 @@ class _CompoundCSR(_CSRBase, Module): def do_finalize(self, busword): raise NotImplementedError + class CSRStatus(_CompoundCSR): def __init__(self, size=1, reset=0, name=None): _CompoundCSR.__init__(self, size, name) @@ -43,6 +47,7 @@ class CSRStatus(_CompoundCSR): self.comb += sc.w.eq(self.status[i*busword:i*busword+nbits]) self.simple_csrs.append(sc) + class CSRStorage(_CompoundCSR): def __init__(self, size=1, reset=0, atomic_write=False, write_from_dev=False, alignment_bits=0, name=None): _CompoundCSR.__init__(self, size, name) @@ -85,18 +90,21 @@ class CSRStorage(_CompoundCSR): self.sync += If(sc.re, self.storage_full[lo:hi].eq(sc.r)) self.sync += self.re.eq(sc.re) + def csrprefix(prefix, csrs, done): for csr in csrs: if csr.huid not in done: csr.name = prefix + csr.name done.add(csr.huid) + def memprefix(prefix, memories, done): for memory in memories: if memory.huid not in done: memory.name_override = prefix + memory.name_override done.add(memory.huid) + class AutoCSR: def get_memories(self): try: diff --git a/migen/bank/eventmanager.py b/migen/bank/eventmanager.py index ad2622f5..effd4e61 100644 --- a/migen/bank/eventmanager.py +++ b/migen/bank/eventmanager.py @@ -3,6 +3,7 @@ from migen.fhdl.std import * from migen.bank.description import * from migen.genlib.misc import optree + class _EventSource(HUID): def __init__(self): HUID.__init__(self) @@ -11,6 +12,7 @@ class _EventSource(HUID): self.trigger = Signal() # trigger signal interface to the user design self.clear = Signal() # clearing attempt by W1C to pending register, ignored by some event sources + # set on a positive trigger pulse class EventSourcePulse(Module, _EventSource): def __init__(self): @@ -21,6 +23,7 @@ class EventSourcePulse(Module, _EventSource): If(self.trigger, self.pending.eq(1)) ] + # set on the falling edge of the trigger, status = trigger class EventSourceProcess(Module, _EventSource): def __init__(self): @@ -33,6 +36,7 @@ class EventSourceProcess(Module, _EventSource): If(~self.trigger & old_trigger, self.pending.eq(1)) ] + # all status set by external trigger class EventSourceLevel(Module, _EventSource): def __init__(self): @@ -42,6 +46,7 @@ class EventSourceLevel(Module, _EventSource): self.pending.eq(self.trigger) ] + class EventManager(Module, AutoCSR): def __init__(self): self.irq = Signal() @@ -71,6 +76,7 @@ class EventManager(Module, AutoCSR): raise FinalizeError self.submodules += value + class SharedIRQ(Module): def __init__(self, *event_managers): self.irq = Signal() diff --git a/migen/bank/wbgen.py b/migen/bank/wbgen.py index ad6b2e97..e7f02242 100644 --- a/migen/bank/wbgen.py +++ b/migen/bank/wbgen.py @@ -2,6 +2,7 @@ from migen.fhdl.std import * from migen.bus import wishbone from migen.bank.bank import GenericBank + class Bank(GenericBank): def __init__(self, description, bus=None): if bus is None: diff --git a/migen/bus/csr.py b/migen/bus/csr.py index 8530c0b8..7c1e6fee 100644 --- a/migen/bus/csr.py +++ b/migen/bus/csr.py @@ -11,15 +11,18 @@ _layout = [ ("dat_r", "data_width", DIR_S_TO_M) ] + class Interface(Record): def __init__(self, data_width=8, address_width=14): Record.__init__(self, set_layout_parameters(_layout, data_width=data_width, address_width=address_width)) + class Interconnect(Module): def __init__(self, master, slaves): self.comb += master.connect(*slaves) + class Initiator(Module): def __init__(self, generator, bus=None): self.generator = generator @@ -55,6 +58,7 @@ class Initiator(Module): selfp.bus.we = 1 selfp.bus.dat_w = self.transaction.data + class SRAM(Module): def __init__(self, mem_or_size, address, read_only=None, init=None, bus=None): if bus is None: diff --git a/migen/bus/memory.py b/migen/bus/memory.py index 621420c1..fc720a2a 100644 --- a/migen/bus/memory.py +++ b/migen/bus/memory.py @@ -1,6 +1,7 @@ from migen.fhdl.std import * from migen.bus.transactions import * + def _byte_mask(orig, dat_w, sel): r = 0 shift = 0 @@ -15,6 +16,7 @@ def _byte_mask(orig, dat_w, sel): shift += 8 return r + class Initiator(Module): def __init__(self, generator, mem): self.generator = generator diff --git a/migen/bus/transactions.py b/migen/bus/transactions.py index fb3a0619..32379e57 100644 --- a/migen/bus/transactions.py +++ b/migen/bus/transactions.py @@ -1,5 +1,6 @@ from migen.fhdl.std import * + class Transaction: def __init__(self, address, data=0, sel=None, busname=None): self.address = address @@ -14,8 +15,10 @@ class Transaction: def __str__(self): return "<" + self.__class__.__name__ + " adr:" + hex(self.address) + " dat:" + hex(self.data) + ">" + class TRead(Transaction): pass + class TWrite(Transaction): pass diff --git a/migen/bus/wishbone.py b/migen/bus/wishbone.py index ef06d25a..494da16b 100644 --- a/migen/bus/wishbone.py +++ b/migen/bus/wishbone.py @@ -19,16 +19,19 @@ _layout = [ ("err", 1, DIR_S_TO_M) ] + class Interface(Record): def __init__(self, data_width=32): Record.__init__(self, set_layout_parameters(_layout, data_width=data_width, sel_width=data_width//8)) + class InterconnectPointToPoint(Module): def __init__(self, master, slave): self.comb += master.connect(slave) + class Arbiter(Module): def __init__(self, masters, target): self.submodules.rr = roundrobin.RoundRobin(len(masters)) @@ -54,6 +57,7 @@ class Arbiter(Module): reqs = [m.cyc for m in masters] self.comb += self.rr.request.eq(Cat(*reqs)) + class Decoder(Module): # slaves is a list of pairs: # 0) function that takes the address signal and returns a FHDL expression @@ -94,12 +98,14 @@ class Decoder(Module): masked = [Replicate(slave_sel_r[i], flen(master.dat_r)) & slaves[i][1].dat_r for i in range(ns)] self.comb += master.dat_r.eq(optree("|", masked)) + class InterconnectShared(Module): def __init__(self, masters, slaves, register=False): shared = Interface() self.submodules += Arbiter(masters, shared) self.submodules += Decoder(shared, slaves, register) + class Crossbar(Module): def __init__(self, masters, slaves, register=False): matches, busses = zip(*slaves) @@ -112,6 +118,7 @@ class Crossbar(Module): for column, bus in zip(zip(*access), busses): self.submodules += Arbiter(column, bus) + class DownConverter(Module): # DownConverter splits Wishbone accesses of N bits in M accesses of L bits where: # N is the original data-width @@ -197,6 +204,7 @@ class DownConverter(Module): ) ) + class Tap(Module): def __init__(self, bus, handler=print): self.bus = bus @@ -215,6 +223,7 @@ class Tap(Module): self.handler(transaction) do_simulation.passive = True + class Initiator(Module): def __init__(self, generator, bus=None): self.generator = generator @@ -251,6 +260,7 @@ class Initiator(Module): selfp.bus.cyc = 0 selfp.bus.stb = 0 + class TargetModel: def read(self, address): return 0 @@ -261,6 +271,7 @@ class TargetModel: def can_ack(self, bus): return True + class Target(Module): def __init__(self, model, bus=None): if bus is None: @@ -281,6 +292,7 @@ class Target(Module): bus.ack = 0 do_simulation.passive = True + class SRAM(Module): def __init__(self, mem_or_size, read_only=None, init=None, bus=None): if bus is None: diff --git a/migen/bus/wishbone2csr.py b/migen/bus/wishbone2csr.py index 9c81ebcf..2d43c77e 100644 --- a/migen/bus/wishbone2csr.py +++ b/migen/bus/wishbone2csr.py @@ -3,6 +3,7 @@ from migen.bus import wishbone from migen.bus import csr from migen.genlib.misc import timeline + class WB2CSR(Module): def __init__(self, bus_wishbone=None, bus_csr=None): if bus_wishbone is None: diff --git a/migen/fhdl/bitcontainer.py b/migen/fhdl/bitcontainer.py index e05b8f45..381afc35 100644 --- a/migen/fhdl/bitcontainer.py +++ b/migen/fhdl/bitcontainer.py @@ -1,5 +1,6 @@ from migen.fhdl import structure as f + def log2_int(n, need_pow2=True): l = 1 r = 0 @@ -10,6 +11,7 @@ def log2_int(n, need_pow2=True): raise ValueError("Not a power of 2") return r + def bits_for(n, require_sign_bit=False): if n > 0: r = log2_int(n + 1, False) @@ -20,6 +22,7 @@ def bits_for(n, require_sign_bit=False): r += 1 return r + def value_bits_sign(v): if isinstance(v, bool): return 1, False @@ -99,6 +102,7 @@ def value_bits_sign(v): raise TypeError("Can not calculate bit length of {} {}".format( type(v), v)) + def flen(v): """Bit length of an expression @@ -120,6 +124,7 @@ def flen(v): """ return value_bits_sign(v)[0] + def fiter(v): """Bit iterator @@ -146,6 +151,7 @@ def fiter(v): else: raise TypeError("Can not bit-iterate {} {}".format(type(v), v)) + def fslice(v, s): """Bit slice @@ -180,6 +186,7 @@ def fslice(v, s): else: raise TypeError("Can not bit-slice {} {}".format(type(v), v)) + def freversed(v): """Bit reverse diff --git a/migen/fhdl/decorators.py b/migen/fhdl/decorators.py index aaa5d56f..7a1f8211 100644 --- a/migen/fhdl/decorators.py +++ b/migen/fhdl/decorators.py @@ -4,6 +4,7 @@ from migen.fhdl.structure import * from migen.fhdl.module import Module from migen.fhdl.tools import insert_reset, rename_clock_domain + class ModuleTransformer: # overload this in derived classes def transform_instance(self, i): @@ -51,10 +52,12 @@ class ModuleTransformer: warnings.warn("deprecated, use the plain transformer", DeprecationWarning, 2) return cls(*args, **kwargs)(i) + def DecorateModule(transformer, *args, **kwargs): warnings.warn("deprecated, use the plain transformer", DeprecationWarning, 2) return transformer.__self__(*args, **kwargs) + class ControlInserter(ModuleTransformer): control_name = None # override this @@ -84,6 +87,7 @@ class ControlInserter(ModuleTransformer): for cdn in self.clock_domains] self.transform_fragment_insert(i, f, to_insert) + class CEInserter(ControlInserter): control_name = "ce" @@ -93,6 +97,7 @@ class CEInserter(ControlInserter): InsertCE = CEInserter.adhoc + class ResetInserter(ControlInserter): control_name = "reset" @@ -102,6 +107,7 @@ class ResetInserter(ControlInserter): InsertReset = ResetInserter.adhoc + class ClockDomainsRenamer(ModuleTransformer): def __init__(self, cd_remapping): if isinstance(cd_remapping, str): diff --git a/migen/fhdl/edif.py b/migen/fhdl/edif.py index ef6663dd..8222bd68 100644 --- a/migen/fhdl/edif.py +++ b/migen/fhdl/edif.py @@ -14,6 +14,7 @@ _Property = namedtuple("_Property", "name value") _Instance = namedtuple("_Instance", "name cell properties") _NetBranch = namedtuple("_NetBranch", "portname instancename") + def _write_cells(cells): r = "" for cell in cells: @@ -32,6 +33,7 @@ def _write_cells(cells): )""" return r + def _write_io(ios): r = "" for s in ios: @@ -39,6 +41,7 @@ def _write_io(ios): (port {0.name} (direction {0.direction}))""".format(s) return r + def _write_instantiations(instances, cell_library): instantiations = "" for instance in instances: @@ -52,6 +55,7 @@ def _write_instantiations(instances, cell_library): )""" return instantiations + def _write_connections(connections): r = "" for netname, branches in connections.items(): @@ -66,6 +70,7 @@ def _write_connections(connections): )""" return r + def _write_edif(cells, ios, instances, connections, cell_library, design_name, part, vendor): r = """(edif {0} (edifVersion 2 0 0) @@ -105,6 +110,7 @@ def _write_edif(cells, ios, instances, connections, cell_library, design_name, p return r + def _generate_cells(f): cell_dict = OrderedDict() for special in f.specials: @@ -130,6 +136,7 @@ def _generate_cells(f): raise ValueError("EDIF conversion can only handle synthesized fragments") return [_Cell(k, v) for k, v in cell_dict.items()] + def _generate_instances(f,ns): instances = [] for special in f.specials: @@ -151,6 +158,7 @@ def _generate_instances(f,ns): raise ValueError("EDIF conversion can only handle synthesized fragments") return instances + def _generate_ios(f, ios, ns): outs = list_special_ios(f, False, True, False) inouts = list_special_ios(f, False, False, True) @@ -160,6 +168,7 @@ def _generate_ios(f, ios, ns): r.append(_Port(name=ns.get_name(io), direction=direction)) return r + def _generate_connections(f, ios, ns): r = OrderedDict() for special in f.specials: @@ -184,6 +193,7 @@ def _generate_connections(f, ios, ns): r[io].append(_NetBranch(portname=io, instancename="")) return r + def convert(f, ios, cell_library, vendor, device, name="top"): if not isinstance(f, _Fragment): f = f.get_fragment() diff --git a/migen/fhdl/module.py b/migen/fhdl/module.py index a08bc680..d51cad29 100644 --- a/migen/fhdl/module.py +++ b/migen/fhdl/module.py @@ -7,24 +7,29 @@ from migen.fhdl.structure import _Fragment from migen.fhdl.tools import rename_clock_domain from migen.sim.upper import gen_sim, proxy_sim + class FinalizeError(Exception): pass + def _flat_list(e): if isinstance(e, collections.Iterable): return flat_iteration(e) else: return [e] + class _ModuleProxy: def __init__(self, fm): object.__setattr__(self, "_fm", fm) + class _ModuleComb(_ModuleProxy): def __iadd__(self, other): self._fm._fragment.comb += _flat_list(other) return self + def _cd_append(d, key, statements): try: l = d[key] @@ -33,6 +38,7 @@ def _cd_append(d, key, statements): d[key] = l l += _flat_list(statements) + class _ModuleSyncCD: def __init__(self, fm, cd): self._fm = fm @@ -42,6 +48,7 @@ class _ModuleSyncCD: _cd_append(self._fm._fragment.sync, self._cd, other) return self + class _ModuleSync(_ModuleProxy): def __iadd__(self, other): _cd_append(self._fm._fragment.sync, "sys", other) @@ -54,6 +61,7 @@ class _ModuleSync(_ModuleProxy): if not isinstance(value, _ModuleSyncCD): raise AttributeError("Attempted to assign sync property - use += instead") + # _ModuleForwardAttr enables user classes to do e.g.: # self.subm.foobar = SomeModule() # and then access the submodule with self.foobar. @@ -62,11 +70,13 @@ class _ModuleForwardAttr: self.__iadd__(value) setattr(self._fm, name, value) + class _ModuleSpecials(_ModuleProxy, _ModuleForwardAttr): def __iadd__(self, other): self._fm._fragment.specials |= set(_flat_list(other)) return self + class _ModuleSubmodules(_ModuleProxy): def __setattr__(self, name, value): self._fm._submodules += [(name, e) for e in _flat_list(value)] @@ -76,11 +86,13 @@ class _ModuleSubmodules(_ModuleProxy): self._fm._submodules += [(None, e) for e in _flat_list(other)] return self + class _ModuleClockDomains(_ModuleProxy, _ModuleForwardAttr): def __iadd__(self, other): self._fm._fragment.clock_domains += _flat_list(other) return self + class Module: def get_fragment(self): assert(not self.get_fragment_called) diff --git a/migen/fhdl/namer.py b/migen/fhdl/namer.py index ea9d5ff9..e0b14fc8 100644 --- a/migen/fhdl/namer.py +++ b/migen/fhdl/namer.py @@ -3,6 +3,7 @@ from itertools import combinations from migen.fhdl.structure import * + class _Node: def __init__(self): self.signal_count = 0 @@ -11,6 +12,7 @@ class _Node: self.use_number = False self.children = OrderedDict() + def _display_tree(filename, tree): from migen.util.treeviz import RenderNode @@ -32,6 +34,7 @@ def _display_tree(filename, tree): top = _to_render_node("top", tree) top.to_svg(filename) + def _build_tree(signals, basic_tree=None): root = _Node() for signal in signals: @@ -60,6 +63,7 @@ def _build_tree(signals, basic_tree=None): current.signal_count += 1 return root + def _set_use_name(node, node_name=""): cnames = [(k, _set_use_name(v, k)) for k, v in node.children.items()] for (c1_prefix, c1_names), (c2_prefix, c2_names) in combinations(cnames, 2): @@ -80,6 +84,7 @@ def _set_use_name(node, node_name=""): return r + def _name_signal(tree, signal): elements = [] treepos = tree @@ -97,9 +102,11 @@ def _name_signal(tree, signal): elements.append(elname) return "_".join(elements) + def _build_pnd_from_tree(tree, signals): return dict((signal, _name_signal(tree, signal)) for signal in signals) + def _invert_pnd(pnd): inv_pnd = dict() for k, v in pnd.items(): @@ -107,6 +114,7 @@ def _invert_pnd(pnd): inv_pnd[v].append(k) return inv_pnd + def _list_conflicting_signals(pnd): inv_pnd = _invert_pnd(pnd) r = set() @@ -115,6 +123,7 @@ def _list_conflicting_signals(pnd): r.update(v) return r + def _set_use_number(tree, signals): for signal in signals: current = tree @@ -124,6 +133,7 @@ def _set_use_number(tree, signals): _debug = False + def _build_pnd_for_group(group_n, signals): basic_tree = _build_tree(signals) _set_use_name(basic_tree) @@ -161,6 +171,7 @@ def _build_pnd_for_group(group_n, signals): return pnd + def _build_signal_groups(signals): r = [] for signal in signals: @@ -181,6 +192,7 @@ def _build_signal_groups(signals): s1 -= s2 return r + def _build_pnd(signals): groups = _build_signal_groups(signals) gpnds = [_build_pnd_for_group(n, gsignals) for n, gsignals in enumerate(groups)] @@ -199,6 +211,7 @@ def _build_pnd(signals): return pnd + def build_namespace(signals): pnd = _build_pnd(signals) ns = Namespace(pnd) @@ -208,6 +221,7 @@ def build_namespace(signals): ns.get_name(signal) return ns + class Namespace: def __init__(self, pnd): self.counts = {} diff --git a/migen/fhdl/simplify.py b/migen/fhdl/simplify.py index 3719a178..7c6a916b 100644 --- a/migen/fhdl/simplify.py +++ b/migen/fhdl/simplify.py @@ -3,6 +3,7 @@ from migen.fhdl.specials import _MemoryPort from migen.fhdl.decorators import ModuleTransformer from migen.util.misc import gcd_multiple + class FullMemoryWE(ModuleTransformer): def transform_fragment(self, i, f): newspecials = set() diff --git a/migen/fhdl/specials.py b/migen/fhdl/specials.py index 8554067a..5b504d01 100644 --- a/migen/fhdl/specials.py +++ b/migen/fhdl/specials.py @@ -6,6 +6,7 @@ from migen.fhdl.tools import * from migen.fhdl.tracer import get_obj_var_name from migen.fhdl.verilog import _printexpr as verilog_printexpr + class Special(HUID): def iter_expressions(self): for x in []: @@ -31,6 +32,7 @@ class Special(HUID): r.update(signals) return r + class Tristate(Special): def __init__(self, target, o, oe, i=None): Special.__init__(self) @@ -60,6 +62,7 @@ class Tristate(Special): r += "\n" return r + class TSTriple: def __init__(self, bits_sign=None, min=None, max=None, reset_o=0, reset_oe=0): self.o = Signal(bits_sign, min=min, max=max, reset=reset_o) @@ -69,6 +72,7 @@ class TSTriple: def get_tristate(self, target): return Tristate(target, self.o, self.oe, self.i) + class Instance(Special): class _IO: def __init__(self, name, expr=None): @@ -169,6 +173,7 @@ class Instance(Special): (READ_FIRST, WRITE_FIRST, NO_CHANGE) = range(3) + class _MemoryPort(Special): def __init__(self, adr, dat_r, we=None, dat_w=None, async_read=False, re=None, we_granularity=0, mode=WRITE_FIRST, @@ -201,6 +206,7 @@ class _MemoryPort(Special): def emit_verilog(port, ns, add_data_file): return "" # done by parent Memory object + class Memory(Special): def __init__(self, width, depth, init=None, name=None): Special.__init__(self) @@ -319,6 +325,7 @@ class Memory(Special): return r + class SynthesisDirective(Special): def __init__(self, template, **signals): Special.__init__(self) diff --git a/migen/fhdl/structure.py b/migen/fhdl/structure.py index 868a743f..f2f424ae 100644 --- a/migen/fhdl/structure.py +++ b/migen/fhdl/structure.py @@ -4,6 +4,7 @@ from collections import defaultdict from migen.fhdl import tracer from migen.util.misc import flat_iteration + class HUID: __next_uid = 0 def __init__(self): @@ -13,6 +14,7 @@ class HUID: def __hash__(self): return self.huid + class Value(HUID): """Base class for operands @@ -116,12 +118,14 @@ class Value(HUID): def __hash__(self): return HUID.__hash__(self) + class _Operator(Value): def __init__(self, op, operands): Value.__init__(self) self.op = op self.operands = operands + def Mux(sel, val1, val0): """Multiplex between two values @@ -141,6 +145,7 @@ def Mux(sel, val1, val0): """ return _Operator("m", [sel, val1, val0]) + class _Slice(Value): def __init__(self, value, start, stop): Value.__init__(self) @@ -148,6 +153,7 @@ class _Slice(Value): self.start = start self.stop = stop + class Cat(Value): """Concatenate values @@ -176,6 +182,7 @@ class Cat(Value): Value.__init__(self) self.l = list(flat_iteration(args)) + class Replicate(Value): """Replicate a value @@ -201,6 +208,7 @@ class Replicate(Value): self.v = v self.n = n + class Signal(Value): """A `Value` that can change @@ -292,6 +300,7 @@ class Signal(Value): from migen.fhdl.bitcontainer import value_bits_sign return cls(bits_sign=value_bits_sign(other), **kwargs) + class ClockSignal(Value): """Clock signal for a given clock domain @@ -307,6 +316,7 @@ class ClockSignal(Value): Value.__init__(self) self.cd = cd + class ResetSignal(Value): """Reset signal for a given clock domain @@ -324,11 +334,13 @@ class ResetSignal(Value): # statements + class _Assign: def __init__(self, l, r): self.l = l self.r = r + class If: """Conditional execution of statements @@ -383,6 +395,7 @@ class If: _insert_else(self, [If(cond, *t)]) return self + def _insert_else(obj, clause): o = obj while o.f: @@ -391,6 +404,7 @@ def _insert_else(obj, clause): o = o.f[0] o.f = clause + class Case: """Case/Switch statement @@ -440,6 +454,7 @@ class Case: # arrays + class _ArrayProxy(Value): def __init__(self, choices, key): self.choices = choices @@ -453,6 +468,7 @@ class _ArrayProxy(Value): return _ArrayProxy([choice.__getitem__(key) for choice in self.choices], self.key) + class Array(list): """Addressable multiplexer @@ -488,6 +504,7 @@ class Array(list): else: return list.__getitem__(self, key) + class ClockDomain: """Synchronous domain @@ -537,6 +554,7 @@ class ClockDomain: if self.rst is not None: self.rst.name_override = new_name + "_rst" + class _ClockDomainList(list): def __getitem__(self, key): if isinstance(key, str): @@ -549,9 +567,11 @@ class _ClockDomainList(list): (SPECIAL_INPUT, SPECIAL_OUTPUT, SPECIAL_INOUT) = range(3) + class StopSimulation(Exception): pass + class _Fragment: def __init__(self, comb=None, sync=None, specials=None, clock_domains=None, sim=None): if comb is None: comb = [] diff --git a/migen/fhdl/tools.py b/migen/fhdl/tools.py index 233c0eba..9a6c3a66 100644 --- a/migen/fhdl/tools.py +++ b/migen/fhdl/tools.py @@ -4,6 +4,7 @@ from migen.fhdl.visit import NodeVisitor, NodeTransformer from migen.fhdl.bitcontainer import value_bits_sign from migen.util.misc import flat_iteration + class _SignalLister(NodeVisitor): def __init__(self): self.output_list = set() @@ -11,6 +12,7 @@ class _SignalLister(NodeVisitor): def visit_Signal(self, node): self.output_list.add(node) + class _TargetLister(NodeVisitor): def __init__(self): self.output_list = set() @@ -29,20 +31,24 @@ class _TargetLister(NodeVisitor): for choice in node.choices: self.visit(choice) + def list_signals(node): lister = _SignalLister() lister.visit(node) return lister.output_list + def list_targets(node): lister = _TargetLister() lister.visit(node) return lister.output_list + def _resort_statements(ol): return [statement for i, statement in sorted(ol, key=lambda x: x[0])] + def group_by_targets(sl): groups = [] seen = set() @@ -63,12 +69,14 @@ def group_by_targets(sl): return [(targets, _resort_statements(stmts)) for targets, stmts in groups] + def list_special_ios(f, ins, outs, inouts): r = set() for special in f.specials: r |= special.list_ios(ins, outs, inouts) return r + class _ClockDomainLister(NodeVisitor): def __init__(self): self.clock_domains = set() @@ -84,11 +92,13 @@ class _ClockDomainLister(NodeVisitor): self.clock_domains.add(clockname) self.visit(statements) + def list_clock_domains_expr(f): cdl = _ClockDomainLister() cdl.visit(f) return cdl.clock_domains + def list_clock_domains(f): r = list_clock_domains_expr(f) for special in f.specials: @@ -97,6 +107,7 @@ def list_clock_domains(f): r.add(cd.name) return r + def is_variable(node): if isinstance(node, Signal): return node.variable @@ -112,13 +123,16 @@ def is_variable(node): else: raise TypeError + def generate_reset(rst, sl): targets = list_targets(sl) return [t.eq(t.reset) for t in sorted(targets, key=lambda x: x.huid)] + def insert_reset(rst, sl): return [If(rst, *generate_reset(rst, sl)).Else(*sl)] + def insert_resets(f): newsync = dict() for k, v in f.sync.items(): @@ -128,6 +142,7 @@ def insert_resets(f): newsync[k] = v f.sync = newsync + class _Lowerer(NodeTransformer): def __init__(self): self.target_context = False @@ -149,6 +164,7 @@ class _Lowerer(NodeTransformer): self.target_context, self.extra_stmts = old_target_context, old_extra_stmts return r + # Basics are FHDL structure elements that back-ends are not required to support # but can be expressed in terms of other elements (lowered) before conversion. class _BasicLowerer(_Lowerer): @@ -177,6 +193,7 @@ class _BasicLowerer(_Lowerer): def visit_ResetSignal(self, node): return self.clock_domains[node.cd].rst + class _ComplexSliceLowerer(_Lowerer): def visit_Slice(self, node): if not isinstance(node.value, Signal): @@ -189,6 +206,7 @@ class _ComplexSliceLowerer(_Lowerer): node = _Slice(slice_proxy, node.start, node.stop) return NodeTransformer.visit_Slice(self, node) + def _apply_lowerer(l, f): f = l.visit(f) f.comb += l.comb @@ -208,12 +226,15 @@ def _apply_lowerer(l, f): return f + def lower_basics(f): return _apply_lowerer(_BasicLowerer(f.clock_domains), f) + def lower_complex_slices(f): return _apply_lowerer(_ComplexSliceLowerer(), f) + class _ClockDomainRenamer(NodeVisitor): def __init__(self, old, new): self.old = old @@ -227,10 +248,12 @@ class _ClockDomainRenamer(NodeVisitor): if node.cd == self.old: node.cd = self.new + def rename_clock_domain_expr(f, old, new): cdr = _ClockDomainRenamer(old, new) cdr.visit(f) + def rename_clock_domain(f, old, new): rename_clock_domain_expr(f, old, new) if old in f.sync: diff --git a/migen/fhdl/tracer.py b/migen/fhdl/tracer.py index ad696608..a394f93f 100644 --- a/migen/fhdl/tracer.py +++ b/migen/fhdl/tracer.py @@ -2,6 +2,7 @@ import inspect from opcode import opname from collections import defaultdict + def get_var_name(frame): code = frame.f_code call_index = frame.f_lasti @@ -29,11 +30,13 @@ def get_var_name(frame): else: return None + def remove_underscore(s): if len(s) > 2 and s[0] == "_" and s[1] != "_": s = s[1:] return s + def get_obj_var_name(override=None, default=None): if override: return override @@ -55,12 +58,14 @@ def get_obj_var_name(override=None, default=None): name_to_idx = defaultdict(int) classname_to_objs = dict() + def index_id(l, obj): for n, e in enumerate(l): if id(e) == id(obj): return n raise ValueError + def trace_back(varname=None): l = [] frame = inspect.currentframe().f_back.f_back diff --git a/migen/fhdl/verilog.py b/migen/fhdl/verilog.py index 46edfd43..4cc657b3 100644 --- a/migen/fhdl/verilog.py +++ b/migen/fhdl/verilog.py @@ -8,6 +8,7 @@ from migen.fhdl.bitcontainer import bits_for, flen from migen.fhdl.namer import Namespace, build_namespace from migen.fhdl.conv_output import ConvOutput + def _printsig(ns, s): if s.signed: n = "signed " @@ -18,6 +19,7 @@ def _printsig(ns, s): n += ns.get_name(s) return n + def _printintbool(node): if isinstance(node, bool): if node: @@ -33,6 +35,7 @@ def _printintbool(node): else: raise TypeError + def _printexpr(ns, node): if isinstance(node, (int, bool)): return _printintbool(node) @@ -96,6 +99,7 @@ def _printexpr(ns, node): (_AT_BLOCKING, _AT_NONBLOCKING, _AT_SIGNAL) = range(3) + def _printnode(ns, at, level, node): if node is None: return "" @@ -138,6 +142,7 @@ def _printnode(ns, at, level, node): else: raise TypeError("Node of unrecognized type: "+str(type(node))) + def _list_comb_wires(f): r = set() groups = group_by_targets(f.comb) @@ -146,6 +151,7 @@ def _list_comb_wires(f): r |= g[0] return r + def _printheader(f, ios, name, ns): sigs = list_signals(f) | list_special_ios(f, True, True, True) special_outs = list_special_ios(f, False, True, True) @@ -180,6 +186,7 @@ def _printheader(f, ios, name, ns): r += "\n" return r + def _printcomb(f, ns, display_run): r = "" if f.comb: @@ -217,6 +224,7 @@ def _printcomb(f, ns, display_run): r += "\n" return r + def _printsync(f, ns): r = "" for k, v in sorted(f.sync.items(), key=itemgetter(0)): @@ -225,6 +233,7 @@ def _printsync(f, ns): r += "end\n\n" return r + def _call_special_classmethod(overrides, obj, method, *args, **kwargs): cl = obj.__class__ if cl in overrides: @@ -234,6 +243,7 @@ def _call_special_classmethod(overrides, obj, method, *args, **kwargs): else: return None + def _lower_specials_step(overrides, specials): f = _Fragment() lowered_specials = set() @@ -244,6 +254,7 @@ def _lower_specials_step(overrides, specials): lowered_specials.add(special) return f, lowered_specials + def _can_lower(overrides, specials): for special in specials: cl = special.__class__ @@ -253,6 +264,7 @@ def _can_lower(overrides, specials): return True return False + def _lower_specials(overrides, specials): f, lowered_specials = _lower_specials_step(overrides, specials) while _can_lower(overrides, f.specials): @@ -262,6 +274,7 @@ def _lower_specials(overrides, specials): f.specials -= lowered_specials2 return f, lowered_specials + def _printspecials(overrides, specials, ns, add_data_file): r = "" for special in sorted(specials, key=lambda x: x.huid): @@ -271,6 +284,7 @@ def _printspecials(overrides, specials, ns, add_data_file): r += pr return r + def convert(f, ios=None, name="top", special_overrides=dict(), create_clock_domains=True, diff --git a/migen/fhdl/visit.py b/migen/fhdl/visit.py index 3a6d7e1c..337f6b3f 100644 --- a/migen/fhdl/visit.py +++ b/migen/fhdl/visit.py @@ -3,6 +3,7 @@ from copy import copy from migen.fhdl.structure import * from migen.fhdl.structure import _Operator, _Slice, _Assign, _ArrayProxy, _Fragment + class NodeVisitor: def visit(self, node): if isinstance(node, (int, bool)): @@ -98,6 +99,7 @@ class NodeVisitor: def visit_unknown(self, node): pass + # Default methods always copy the node, except for: # - Signals, ClockSignals and ResetSignals # - Unknown objects diff --git a/migen/flow/actor.py b/migen/flow/actor.py index a92d1aa9..dad0f64a 100644 --- a/migen/flow/actor.py +++ b/migen/flow/actor.py @@ -3,6 +3,7 @@ from migen.fhdl.std import * from migen.genlib.misc import optree from migen.genlib.record import * + def _make_m2s(layout): r = [] for f in layout: @@ -12,6 +13,7 @@ def _make_m2s(layout): r.append((f[0], _make_m2s(f[1]))) return r + class EndpointDescription: def __init__(self, payload_layout, param_layout=[], packetized=False): self.payload_layout = payload_layout @@ -56,14 +58,17 @@ class _Endpoint(Record): except: return getattr(object.__getattribute__(self, "param"), name) + class Source(_Endpoint): def connect(self, sink): return Record.connect(self, sink) + class Sink(_Endpoint): def connect(self, source): return source.connect(self) + def get_endpoints(obj, filt=_Endpoint): if hasattr(obj, "get_endpoints") and callable(obj.get_endpoints): return obj.get_endpoints(filt) @@ -73,12 +78,14 @@ def get_endpoints(obj, filt=_Endpoint): r[k] = v return r + def get_single_ep(obj, filt): eps = get_endpoints(obj, filt) if len(eps) != 1: raise ValueError("More than one endpoint") return list(eps.items())[0] + class BinaryActor(Module): def __init__(self, *args, **kwargs): self.busy = Signal() @@ -89,6 +96,7 @@ class BinaryActor(Module): def build_binary_control(self, sink, source): raise NotImplementedError("Binary actor classes must overload build_binary_control_fragment") + class CombinatorialActor(BinaryActor): def build_binary_control(self, sink, source): self.comb += [ @@ -102,6 +110,7 @@ class CombinatorialActor(BinaryActor): source.eop.eq(sink.eop) ] + class SequentialActor(BinaryActor): def __init__(self, delay): self.trigger = Signal() @@ -134,6 +143,7 @@ class SequentialActor(BinaryActor): source.eop.eq(sink.eop) ] + class PipelinedActor(BinaryActor): def __init__(self, latency): self.pipe_ce = Signal() diff --git a/migen/flow/hooks.py b/migen/flow/hooks.py index d92afb41..d8e97b4f 100644 --- a/migen/flow/hooks.py +++ b/migen/flow/hooks.py @@ -3,6 +3,7 @@ from collections import defaultdict from migen.fhdl.std import * from migen.flow.actor import * + class EndpointSimHook(Module): def __init__(self, endpoint): self.endpoint = endpoint @@ -25,6 +26,7 @@ class EndpointSimHook(Module): else: self.on_inactive() + class DFGHook(Module): def __init__(self, dfg, create): assert(not dfg.is_abstract()) diff --git a/migen/flow/isd.py b/migen/flow/isd.py index 2936aca5..44be71b3 100644 --- a/migen/flow/isd.py +++ b/migen/flow/isd.py @@ -4,6 +4,7 @@ from migen.flow.hooks import DFGHook ISD_MAGIC = 0x6ab4 + class EndpointReporter(Module, AutoCSR): def __init__(self, endpoint, nbits): self.reset = Signal() @@ -43,6 +44,7 @@ class EndpointReporter(Module, AutoCSR): ) ] + class DFGReporter(DFGHook, AutoCSR): def __init__(self, dfg, nbits): self._magic = CSRStatus(16) diff --git a/migen/flow/network.py b/migen/flow/network.py index 9d02e470..0c29ad70 100644 --- a/migen/flow/network.py +++ b/migen/flow/network.py @@ -9,6 +9,7 @@ from migen.flow import plumbing # from the dictionary. They are needed to enable actor duplication or sharing during # elaboration, and automatic parametrization of plumbing actors. + class AbstractActor: def __init__(self, actor_class, parameters=dict(), name=None): self.actor_class = actor_class @@ -26,6 +27,7 @@ class AbstractActor: r += ">" return r + class MultiDiGraph: def __init__(self): self.edges = defaultdict(list) @@ -89,6 +91,7 @@ class MultiDiGraph: e.append((source, sink, edge)) return e + # TODO: rewrite this without non-determinism class DataFlowGraph(MultiDiGraph): def __init__(self): @@ -280,6 +283,7 @@ class DataFlowGraph(MultiDiGraph): optimizer(self) self._instantiate_actors() + class CompositeActor(Module): def __init__(self, dfg): dfg.elaborate() diff --git a/migen/flow/perftools.py b/migen/flow/perftools.py index 2132c2a0..0072b66d 100644 --- a/migen/flow/perftools.py +++ b/migen/flow/perftools.py @@ -1,5 +1,6 @@ from migen.flow.hooks import * + class EndpointReporter(EndpointSimHook): def __init__(self, endpoint): EndpointSimHook.__init__(self, endpoint) @@ -37,6 +38,7 @@ class EndpointReporter(EndpointSimHook): def on_inactive(self): self.inactive += 1 + class DFGReporter(DFGHook): def __init__(self, dfg): DFGHook.__init__(self, dfg, lambda u, ep, v: EndpointReporter(getattr(u, ep))) diff --git a/migen/flow/plumbing.py b/migen/flow/plumbing.py index 5bfb4935..85d0ceaf 100644 --- a/migen/flow/plumbing.py +++ b/migen/flow/plumbing.py @@ -3,6 +3,7 @@ from migen.flow.actor import * from migen.genlib.record import * from migen.genlib.misc import optree + class Buffer(PipelinedActor): def __init__(self, layout): self.d = Sink(layout) @@ -14,6 +15,7 @@ class Buffer(PipelinedActor): self.q.param.eq(self.d.param) ) + class Combinator(Module): def __init__(self, layout, subrecords): self.source = Source(layout) @@ -34,6 +36,7 @@ class Combinator(Module): self.comb += [self.source.payload.eq(sink.payload) for sink in sinks] self.comb += [self.source.param.eq(sink.param) for sink in sinks] + class Splitter(Module): def __init__(self, layout, subrecords): self.sink = Sink(layout) @@ -58,6 +61,7 @@ class Splitter(Module): for n, s in enumerate(sources): self.comb += s.stb.eq(self.sink.stb & ~already_acked[n]) + class Multiplexer(Module): def __init__(self, layout, n): self.source = Source(layout) @@ -76,6 +80,7 @@ class Multiplexer(Module): cases[i] = Record.connect(sink, self.source) self.comb += Case(self.sel, cases) + class Demultiplexer(Module): def __init__(self, layout, n): self.sink = Sink(layout) diff --git a/migen/genlib/cdc.py b/migen/genlib/cdc.py index 1b2dceb5..ae04c093 100644 --- a/migen/genlib/cdc.py +++ b/migen/genlib/cdc.py @@ -3,6 +3,7 @@ from migen.fhdl.bitcontainer import value_bits_sign from migen.fhdl.specials import Special from migen.fhdl.tools import list_signals + class NoRetiming(Special): def __init__(self, reg): Special.__init__(self) @@ -13,6 +14,7 @@ class NoRetiming(Special): def lower(dr): return Module() + class MultiRegImpl(Module): def __init__(self, i, o, odomain, n): self.i = i @@ -32,6 +34,7 @@ class MultiRegImpl(Module): self.comb += self.o.eq(src) self.specials += [NoRetiming(reg) for reg in self.regs] + class MultiReg(Special): def __init__(self, i, o, odomain="sys", n=2): Special.__init__(self) @@ -58,6 +61,7 @@ class MultiReg(Special): def lower(dr): return MultiRegImpl(dr.i, dr.o, dr.odomain, dr.n) + class PulseSynchronizer(Module): def __init__(self, idomain, odomain): self.i = Signal() @@ -77,6 +81,7 @@ class PulseSynchronizer(Module): sync_o += toggle_o_r.eq(toggle_o) self.comb += self.o.eq(toggle_o ^ toggle_o_r) + class GrayCounter(Module): def __init__(self, width): self.ce = Signal() diff --git a/migen/genlib/coding.py b/migen/genlib/coding.py index c12b4066..21366f2c 100644 --- a/migen/genlib/coding.py +++ b/migen/genlib/coding.py @@ -4,6 +4,7 @@ from migen.fhdl.std import * Encoders and decoders between binary and one-hot representation """ + class Encoder(Module): """Encode one-hot to binary @@ -32,6 +33,7 @@ class Encoder(Module): act["default"] = self.n.eq(1) self.comb += Case(self.i, act) + class PriorityEncoder(Module): """Priority encode requests to binary @@ -60,6 +62,7 @@ class PriorityEncoder(Module): self.comb += If(self.i[j], self.o.eq(j)) self.comb += self.n.eq(self.i == 0) + class Decoder(Module): """Decode binary to one-hot @@ -89,5 +92,6 @@ class Decoder(Module): self.comb += Case(self.i, act) self.comb += If(self.n, self.o.eq(0)) + class PriorityDecoder(Decoder): pass # same diff --git a/migen/genlib/complex.py b/migen/genlib/complex.py index e7dbc358..79dff544 100644 --- a/migen/genlib/complex.py +++ b/migen/genlib/complex.py @@ -1,5 +1,6 @@ from migen.fhdl.std import * + class Complex: def __init__(self, real, imag): self.real = real @@ -46,6 +47,7 @@ class Complex: else: return self.real.eq(r), self.imag.eq(0) + def SignalC(*args, **kwargs): real = Signal(*args, **kwargs) imag = Signal(*args, **kwargs) diff --git a/migen/genlib/divider.py b/migen/genlib/divider.py index 575cc4a4..cb1426cf 100644 --- a/migen/genlib/divider.py +++ b/migen/genlib/divider.py @@ -1,5 +1,6 @@ from migen.fhdl.std import * + class Divider(Module): def __init__(self, w): self.start_i = Signal() diff --git a/migen/genlib/fifo.py b/migen/genlib/fifo.py index f976cdfe..d54303fc 100644 --- a/migen/genlib/fifo.py +++ b/migen/genlib/fifo.py @@ -2,6 +2,7 @@ from migen.fhdl.std import * from migen.genlib.cdc import NoRetiming, MultiReg, GrayCounter from migen.genlib.record import layout_len, Record + def _inc(signal, modulo): if modulo == 2**flen(signal): return signal.eq(signal + 1) @@ -12,6 +13,7 @@ def _inc(signal, modulo): signal.eq(signal + 1) ) + class _FIFOInterface: """ Data written to the input interface (`din`, `we`, `writable`) is @@ -63,6 +65,7 @@ class _FIFOInterface: self.dout_bits = self.dout self.width = width_or_layout + class SyncFIFO(Module, _FIFOInterface): """Synchronous FIFO (first in, first out) @@ -130,6 +133,7 @@ class SyncFIFO(Module, _FIFOInterface): self.readable.eq(self.level != 0) ] + class SyncFIFOBuffered(Module, _FIFOInterface): def __init__(self, width_or_layout, depth): _FIFOInterface.__init__(self, width_or_layout, depth) @@ -154,6 +158,7 @@ class SyncFIFOBuffered(Module, _FIFOInterface): ) self.comb += self.level.eq(fifo.level + self.readable) + class AsyncFIFO(Module, _FIFOInterface): """Asynchronous FIFO (first in, first out) diff --git a/migen/genlib/fsm.py b/migen/genlib/fsm.py index dbadfd70..6ad3083c 100644 --- a/migen/genlib/fsm.py +++ b/migen/genlib/fsm.py @@ -5,20 +5,24 @@ from migen.fhdl.module import FinalizeError from migen.fhdl.visit import NodeTransformer from migen.fhdl.bitcontainer import value_bits_sign + class AnonymousState: pass + # do not use namedtuple here as it inherits tuple # and the latter is used elsewhere in FHDL class NextState: def __init__(self, state): self.state = state + class NextValue: def __init__(self, register, value): self.register = register self.value = value + class _LowerNext(NodeTransformer): def __init__(self, next_state_signal, encoding, aliases): self.next_state_signal = next_state_signal @@ -46,6 +50,7 @@ class _LowerNext(NodeTransformer): else: return node + class FSM(Module): def __init__(self, reset_state=None): self.actions = OrderedDict() diff --git a/migen/genlib/io.py b/migen/genlib/io.py index da0b1cd5..a26a1d99 100644 --- a/migen/genlib/io.py +++ b/migen/genlib/io.py @@ -2,6 +2,7 @@ from migen.fhdl.std import * from migen.fhdl.specials import Special from migen.fhdl.tools import list_signals + class DifferentialInput(Special): def __init__(self, i_p, i_n, o): Special.__init__(self) @@ -18,6 +19,7 @@ class DifferentialInput(Special): def lower(dr): raise NotImplementedError("Attempted to use a differential input, but platform does not support them") + class DifferentialOutput(Special): def __init__(self, i, o_p, o_n): Special.__init__(self) @@ -34,6 +36,7 @@ class DifferentialOutput(Special): def lower(dr): raise NotImplementedError("Attempted to use a differential output, but platform does not support them") + class CRG(Module): def __init__(self, clk, rst=0): self.clock_domains.cd_sys = ClockDomain() @@ -53,6 +56,7 @@ class CRG(Module): self.cd_sys.rst.eq(~rst_n) ] + class DDRInput(Special): def __init__(self, i, o1, o2, clk=ClockSignal()): Special.__init__(self) @@ -71,6 +75,7 @@ class DDRInput(Special): def lower(dr): raise NotImplementedError("Attempted to use a DDR input, but platform does not support them") + class DDROutput(Special): def __init__(self, i1, i2, o, clk=ClockSignal()): Special.__init__(self) diff --git a/migen/genlib/misc.py b/migen/genlib/misc.py index 89ea0380..fc7528a6 100644 --- a/migen/genlib/misc.py +++ b/migen/genlib/misc.py @@ -1,6 +1,7 @@ from migen.fhdl.std import * from migen.fhdl.structure import _Operator + def optree(op, operands, lb=None, ub=None, default=None): if lb is None: lb = 0 @@ -20,6 +21,7 @@ def optree(op, operands, lb=None, ub=None, default=None): [optree(op, operands, lb, s, default), optree(op, operands, s, ub, default)]) + def split(v, *counts): r = [] offset = 0 @@ -31,6 +33,7 @@ def split(v, *counts): offset += n return tuple(r) + def displacer(signal, shift, output, n=None, reverse=False): if shift is None: return output.eq(signal) @@ -44,6 +47,7 @@ def displacer(signal, shift, output, n=None, reverse=False): l = [Replicate(shift == i, w) & signal for i in r] return output.eq(Cat(*l)) + def chooser(signal, shift, output, n=None, reverse=False): if shift is None: return output.eq(signal) @@ -59,6 +63,7 @@ def chooser(signal, shift, output, n=None, reverse=False): cases[i] = [output.eq(signal[s*w:(s+1)*w])] return Case(shift, cases).makedefault() + def timeline(trigger, events): lastevent = max([e[0] for e in events]) counter = Signal(max=lastevent+1) @@ -86,6 +91,7 @@ def timeline(trigger, events): sync.append(counterlogic) return sync + @ResetInserter() @CEInserter() class FlipFlop(Module): @@ -94,6 +100,7 @@ class FlipFlop(Module): self.q = Signal(*args, **kwargs) self.sync += self.q.eq(self.d) + @ResetInserter() @CEInserter() class Counter(Module): @@ -102,6 +109,7 @@ class Counter(Module): self.width = flen(self.value) self.sync += self.value.eq(self.value+increment) + @ResetInserter() @CEInserter() class Timeout(Module): diff --git a/migen/genlib/record.py b/migen/genlib/record.py index 084ba9ce..3a66e221 100644 --- a/migen/genlib/record.py +++ b/migen/genlib/record.py @@ -11,6 +11,7 @@ from migen.genlib.misc import optree # size can be an int, or a (int, bool) tuple for signed numbers # sublayout must be a list + def set_layout_parameters(layout, **layout_dict): def resolve(p): if isinstance(p, str): @@ -34,6 +35,7 @@ def set_layout_parameters(layout, **layout_dict): raise TypeError return r + def layout_len(layout): r = 0 for f in layout: @@ -53,12 +55,14 @@ def layout_len(layout): r += fsize return r + def layout_get(layout, name): for f in layout: if f[0] == name: return f raise KeyError(name) + def layout_partial(layout, *elements): r = [] for path in elements: @@ -77,6 +81,7 @@ def layout_partial(layout, *elements): insert_ref.append(layout_get(copy_ref, last)) return r + class Record: def __init__(self, layout, name=None): self.name = get_obj_var_name(name, "") diff --git a/migen/genlib/resetsync.py b/migen/genlib/resetsync.py index 456c68b1..2f635771 100644 --- a/migen/genlib/resetsync.py +++ b/migen/genlib/resetsync.py @@ -2,6 +2,7 @@ from migen.fhdl.std import * from migen.fhdl.specials import Special from migen.fhdl.tools import list_signals + class AsyncResetSynchronizer(Special): def __init__(self, cd, async_reset): Special.__init__(self) diff --git a/migen/genlib/rob.py b/migen/genlib/rob.py index dbbea870..1c94c463 100644 --- a/migen/genlib/rob.py +++ b/migen/genlib/rob.py @@ -1,5 +1,6 @@ from migen.fhdl.std import * + class ReorderSlot: def __init__(self, tag_width, data_width): self.wait_data = Signal() @@ -7,6 +8,7 @@ class ReorderSlot: self.tag = Signal(tag_width) self.data = Signal(data_width) + class ReorderBuffer(Module): def __init__(self, tag_width, data_width, depth): # issue diff --git a/migen/genlib/roundrobin.py b/migen/genlib/roundrobin.py index d0f34d6b..2d28b8a4 100644 --- a/migen/genlib/roundrobin.py +++ b/migen/genlib/roundrobin.py @@ -2,6 +2,7 @@ from migen.fhdl.std import * (SP_WITHDRAW, SP_CE) = range(2) + class RoundRobin(Module): def __init__(self, n, switch_policy=SP_WITHDRAW): self.request = Signal(n) diff --git a/migen/genlib/sort.py b/migen/genlib/sort.py index 5c73097e..168f51c2 100644 --- a/migen/genlib/sort.py +++ b/migen/genlib/sort.py @@ -1,6 +1,7 @@ from migen.fhdl.std import * from migen.fhdl import verilog + class BitonicSort(Module): """Combinatorial sorting network diff --git a/migen/sim/generic.py b/migen/sim/generic.py index e9dd52ca..a5dd9214 100644 --- a/migen/sim/generic.py +++ b/migen/sim/generic.py @@ -6,6 +6,7 @@ from migen.fhdl import verilog from migen.sim.ipc import * from migen.sim import icarus + class TopLevel: def __init__(self, vcd_name=None, vcd_level=1, top_name="top", dut_type="dut", dut_name="dut", @@ -72,6 +73,7 @@ end r += "\nendmodule" return r + class Simulator: def __init__(self, fragment, top_level=None, sim_runner=None, sockaddr="simsocket", **vopts): if not isinstance(fragment, _Fragment): @@ -211,6 +213,7 @@ class Simulator: def __exit__(self, type, value, traceback): self.close() + def run_simulation(fragment, ncycles=None, vcd_name=None, **kwargs): with Simulator(fragment, TopLevel(vcd_name), icarus.Runner(**kwargs)) as s: s.run(ncycles) diff --git a/migen/sim/ipc.py b/migen/sim/ipc.py index b0266aec..04e39403 100644 --- a/migen/sim/ipc.py +++ b/migen/sim/ipc.py @@ -8,9 +8,11 @@ import os # Message classes # + class Int32(int): pass + class Message: def __init__(self, *pvalues): for parameter, value in zip(self.parameters, pvalues): @@ -26,22 +28,27 @@ class Message: pf = "" return "<" + self.__class__.__name__ + pf + ">" + class MessageTick(Message): code = 0 parameters = [] + class MessageGo(Message): code = 1 parameters = [] + class MessageWrite(Message): code = 2 parameters = [(str, "name"), (Int32, "index"), (int, "value")] + class MessageRead(Message): code = 3 parameters = [(str, "name"), (Int32, "index")] + class MessageReadReply(Message): code = 4 parameters = [(int, "value")] @@ -52,6 +59,7 @@ message_classes = [MessageTick, MessageGo, MessageWrite, MessageRead, MessageRea # Packing # + def _pack_int(v): if v == 0: p = [1, 0] @@ -63,11 +71,13 @@ def _pack_int(v): p.insert(0, len(p)) return p + def _pack_str(v): p = [ord(c) for c in v] p.append(0) return p + def _pack_int32(v): return [ v & 0xff, @@ -76,6 +86,7 @@ def _pack_int32(v): (v & 0xff000000) >> 24 ] + def _pack(message): r = [message.code] for t, p in message.parameters: @@ -95,6 +106,7 @@ def _pack(message): # Unpacking # + def _unpack_int(i, nchunks=None): v = 0 power = 1 @@ -105,6 +117,7 @@ def _unpack_int(i, nchunks=None): power *= 256 return v + def _unpack_str(i): v = "" c = next(i) @@ -113,6 +126,7 @@ def _unpack_str(i): c = next(i) return v + def _unpack(message): i = iter(message) code = next(i) @@ -134,9 +148,11 @@ def _unpack(message): # I/O # + class PacketTooLarge(Exception): pass + class Initiator: def __init__(self, sockaddr): self.sockaddr = sockaddr diff --git a/migen/sim/upper.py b/migen/sim/upper.py index 0c8789dc..05ba3fbc 100644 --- a/migen/sim/upper.py +++ b/migen/sim/upper.py @@ -1,6 +1,7 @@ from migen.fhdl.structure import Signal, StopSimulation from migen.fhdl.specials import Memory + class MemoryProxy: def __init__(self, simulator, obj): self.simulator = simulator @@ -23,6 +24,7 @@ class MemoryProxy: for i, v in zip(range(start, stop, step), value): self.simulator.wr(self._simproxy_obj, i, v) + class Proxy: def __init__(self, simulator, obj): object.__setattr__(self, "simulator", simulator) @@ -52,6 +54,7 @@ class Proxy: assert(isinstance(item, Signal)) self.simulator.wr(item, value) + def gen_sim(simg): gens = dict() resume_cycle = 0 diff --git a/migen/test/support.py b/migen/test/support.py index f0dc77ae..c4a8c7d7 100644 --- a/migen/test/support.py +++ b/migen/test/support.py @@ -2,12 +2,14 @@ from migen.fhdl.std import * from migen.sim.generic import run_simulation from migen.fhdl import verilog + class SimBench(Module): callback = None def do_simulation(self, selfp): if self.callback is not None: return self.callback(self, selfp) + class SimCase: TestBench = SimBench diff --git a/migen/test/test_actor.py b/migen/test/test_actor.py index 9bd65ac2..1963d590 100644 --- a/migen/test/test_actor.py +++ b/migen/test/test_actor.py @@ -8,29 +8,34 @@ from migen.actorlib.sim import * from migen.test.support import SimCase, SimBench + def source_gen(sent): for i in range(10): yield Token("source", {"value": i}) sent.append(i) + class SimSource(SimActor): def __init__(self): self.source = Source([("value", 32)]) self.sent = [] SimActor.__init__(self, source_gen(self.sent)) + def sink_gen(received): while True: t = Token("sink") yield t received.append(t.value["value"]) + class SimSink(SimActor): def __init__(self): self.sink = Sink([("value", 32)]) self.received = [] SimActor.__init__(self, sink_gen(self.received)) + class SourceSinkCase(SimCase, unittest.TestCase): class TestBench(SimBench): def __init__(self): @@ -48,6 +53,7 @@ class SourceSinkCase(SimCase, unittest.TestCase): self.run_with(lambda tb, tbp: None) self.assertEqual(self.tb.source.sent, self.tb.sink.received) + class SourceSinkDirectCase(SimCase, unittest.TestCase): class TestBench(SimBench): def __init__(self): diff --git a/migen/test/test_coding.py b/migen/test/test_coding.py index d8aabe2b..d5d91272 100644 --- a/migen/test/test_coding.py +++ b/migen/test/test_coding.py @@ -5,6 +5,7 @@ from migen.genlib.coding import * from migen.test.support import SimCase, SimBench + class EncCase(SimCase, unittest.TestCase): class TestBench(SimBench): def __init__(self): @@ -26,6 +27,7 @@ class EncCase(SimCase, unittest.TestCase): self.assertEqual(tbp.dut.i, 1<