avoid forking migen, we will add custom modules in litex/gen but will use upstream...
authorFlorent Kermarrec <florent@enjoy-digital.fr>
Wed, 11 Nov 2015 11:10:55 +0000 (12:10 +0100)
committerFlorent Kermarrec <florent@enjoy-digital.fr>
Wed, 11 Nov 2015 11:10:55 +0000 (12:10 +0100)
86 files changed:
README
litex/boards/targets/de0nano.py
litex/boards/targets/kc705.py
litex/boards/targets/minispartan6.py
litex/boards/targets/papilio_pro.py
litex/boards/targets/pipistrello.py
litex/boards/targets/sim.py
litex/boards/targets/simple.py
litex/build/altera/common.py
litex/build/altera/quartus.py
litex/build/generic_platform.py
litex/build/lattice/common.py
litex/build/lattice/diamond.py
litex/build/sim/verilator.py
litex/build/xilinx/common.py
litex/build/xilinx/ise.py
litex/build/xilinx/vivado.py
litex/gen/MIGEN_LICENSE [deleted file]
litex/gen/__init__.py
litex/gen/fhdl/__init__.py [deleted file]
litex/gen/fhdl/bitcontainer.py [deleted file]
litex/gen/fhdl/conv_output.py [deleted file]
litex/gen/fhdl/decorators.py [deleted file]
litex/gen/fhdl/edif.py [deleted file]
litex/gen/fhdl/module.py [deleted file]
litex/gen/fhdl/namer.py [deleted file]
litex/gen/fhdl/simplify.py [deleted file]
litex/gen/fhdl/specials.py [deleted file]
litex/gen/fhdl/structure.py [deleted file]
litex/gen/fhdl/tools.py [deleted file]
litex/gen/fhdl/tracer.py [deleted file]
litex/gen/fhdl/verilog.py [deleted file]
litex/gen/fhdl/visit.py [deleted file]
litex/gen/genlib/__init__.py [deleted file]
litex/gen/genlib/cdc.py [deleted file]
litex/gen/genlib/coding.py [deleted file]
litex/gen/genlib/divider.py [deleted file]
litex/gen/genlib/fifo.py [deleted file]
litex/gen/genlib/fsm.py [deleted file]
litex/gen/genlib/io.py [deleted file]
litex/gen/genlib/misc.py [deleted file]
litex/gen/genlib/record.py [deleted file]
litex/gen/genlib/resetsync.py [deleted file]
litex/gen/genlib/roundrobin.py [deleted file]
litex/gen/genlib/sort.py [deleted file]
litex/gen/sim/__init__.py [deleted file]
litex/gen/sim/core.py [deleted file]
litex/gen/sim/vcd.py [deleted file]
litex/gen/util/__init__.py [deleted file]
litex/gen/util/misc.py [deleted file]
litex/soc/cores/cpu/lm32/core.py
litex/soc/cores/cpu/mor1kx/core.py
litex/soc/cores/flash/nor_flash_16.py
litex/soc/cores/flash/spi_flash.py
litex/soc/cores/gpio.py
litex/soc/cores/identifier.py
litex/soc/cores/sdram/lasmicon/bankmachine.py
litex/soc/cores/sdram/lasmicon/core.py
litex/soc/cores/sdram/lasmicon/multiplexer.py
litex/soc/cores/sdram/lasmicon/perf.py
litex/soc/cores/sdram/lasmicon/refresher.py
litex/soc/cores/sdram/minicon/core.py
litex/soc/cores/sdram/model.py
litex/soc/cores/sdram/phy/gensdrphy.py
litex/soc/cores/sdram/phy/k7ddrphy.py
litex/soc/cores/sdram/phy/s6ddrphy.py
litex/soc/cores/sdram/settings.py
litex/soc/cores/sdram/tester.py
litex/soc/cores/spi/core.py
litex/soc/cores/spi/test.py
litex/soc/cores/timer.py
litex/soc/cores/uart/core.py
litex/soc/integration/cpu_interface.py
litex/soc/integration/sdram_init.py
litex/soc/integration/soc_core.py
litex/soc/integration/soc_sdram.py
litex/soc/interconnect/csr.py
litex/soc/interconnect/csr_bus.py
litex/soc/interconnect/csr_eventmanager.py
litex/soc/interconnect/dfi.py
litex/soc/interconnect/dma_lasmi.py
litex/soc/interconnect/lasmi_bus.py
litex/soc/interconnect/stream.py
litex/soc/interconnect/wishbone.py
litex/soc/interconnect/wishbone2csr.py
litex/soc/interconnect/wishbone2lasmi.py

diff --git a/README b/README
index b11280616190467ab867003c05cc4d2077590075..3f792aab6d4a10a29f6e75e13ceb3149e0283aa0 100644 (file)
--- a/README
+++ b/README
@@ -2,29 +2,32 @@
                       / /  (_) /____ | |/_/
                      / /__/ / __/ -_)>  <
                     /____/_/\__/\__/_/|_|
+                         Migen inside
 
                 Build your hardware, easily!
                 Copyright 2015 Enjoy-Digital
 
 [> Intro
 ---------
-LiteX is an alternative (fork) to Migen/MiSoC maintained and used by Enjoy-Digital
-to build our cores, integrate them in complete SoC and load/flash them to the
-hardware.
+LiteX is an alternative to MiSoC maintained and used by Enjoy-Digital to build 
+our cores, integrate them in complete SoC and load/flash them to the hardware.
 
-The structure of LiteX is kept close to Migen/MiSoC to ease collaboration
-between projects.
+The structure of LiteX is kept close to MiSoC to ease collaboration between 
+projects.
+
+LiteX is based on Migen.
 
 [> License
 -----------
 LiteX is copyright (c) 2015 Enjoy-Digital under BSD Lisense.
-Since it is based on MiSoC/Migen, please also refer to LICENSE files in soc/gen 
-directories or git history to get correct copyrights.
+Since it is based on MiSoC, please also refer to LICENSE file in soc directory
+or git history to get correct copyrights.
 
 [> Sub-packages
------------
+----------------
 gen:
-  Provides tools and simple modules to generate HDL.
+  Provides specific or experimentatl modules to generate HDL that are not integrated
+  in Migen.
 
 build:
   Provides tools to build FPGA bitstreams (interface to vendor toolchains) and to
index 790c69fe2592d8ce16ab4a8be6011f9ab5c03fb2..2e8710b3ea47fd93fc1cc5820107ae4db4845e4f 100644 (file)
@@ -2,7 +2,7 @@
 
 import argparse
 
-from litex.gen import *
+from migen import *
 from litex.boards.platforms import de0nano
 
 from litex.soc.cores.sdram.settings import IS42S16160
index b63a9fc8d9f99efcb3d890eff2084318c83273bf..3d2af43c72f684d47b531bf2f01df692c7fecc04 100644 (file)
@@ -2,8 +2,8 @@
 
 import argparse
 
-from litex.gen import *
-from litex.gen.genlib.resetsync import AsyncResetSynchronizer
+from migen import *
+from migen.genlib.resetsync import AsyncResetSynchronizer
 from litex.boards.platforms import kc705
 
 from litex.soc.cores.sdram.settings import MT8JTF12864
index 7fead6956c79db574c37fde0e7354f7a4fdb3fe8..b9f1f4e23ba119a824963fad61715e2bec7a37ce 100644 (file)
@@ -3,8 +3,8 @@
 import argparse
 from fractions import Fraction
 
-from litex.gen import *
-from litex.gen.genlib.resetsync import AsyncResetSynchronizer
+from migen import *
+from migen.genlib.resetsync import AsyncResetSynchronizer
 from litex.boards.platforms import minispartan6
 
 from litex.soc.cores.sdram.settings import AS4C16M16
index 9e7a86e166c8c01ae828454c40967e30b3755fee..011232ec7141e613289c3279f80ea44257e07e3c 100644 (file)
@@ -3,8 +3,8 @@
 import argparse
 from fractions import Fraction
 
-from litex.gen import *
-from litex.gen.genlib.resetsync import AsyncResetSynchronizer
+from migen import *
+from migen.genlib.resetsync import AsyncResetSynchronizer
 from litex.boards.platforms import papilio_pro
 
 from litex.soc.cores.sdram.settings import MT48LC4M16
index 6ec6fc4b5d6cc83d38856ce157544c04dde63eaf..748350e1ac965f45b1a87ff2b4fce9525374ac8a 100644 (file)
@@ -3,8 +3,8 @@
 import argparse
 from fractions import Fraction
 
-from litex.gen import *
-from litex.gen.genlib.resetsync import AsyncResetSynchronizer
+from migen import *
+from migen.genlib.resetsync import AsyncResetSynchronizer
 from litex.boards.platforms import pipistrello
 
 from litex.soc.cores.sdram_settings import MT46H32M16
index 0990ac6add91064de94ecf2696fd1e789c7eaa2a..d1d35131ad5555d8453d540b51a4f82b93a783cd 100644 (file)
@@ -3,9 +3,9 @@
 import argparse
 import importlib
 
-from litex.gen import *
+from migen import *
 from litex.boards.platforms import sim
-from litex.gen.genlib.io import CRG
+from migen.genlib.io import CRG
 
 from litex.soc.integration.soc_sdram import *
 from litex.soc.integration.builder import *
index 8ac275058397a62867d7dba3ec27562c00543a3e..d1aed7bb94c7b349e786db6fa4f4e49bb5262c98 100644 (file)
@@ -3,8 +3,8 @@
 import argparse
 import importlib
 
-from litex.gen import *
-from litex.gen.genlib.io import CRG
+from migen import *
+from migen.genlib.io import CRG
 
 from litex.soc.integration.soc_core import *
 from litex.soc.integration.builder import *
index 07b6ef76acceb5d1809739a6b26b90f4b2522c35..fafb4983796d4054374df9379dbe1037732e5fde 100644 (file)
@@ -1,6 +1,6 @@
-from litex.gen.fhdl.module import Module
-from litex.gen.fhdl.specials import Instance
-from litex.gen.genlib.io import DifferentialInput, DifferentialOutput
+from migen.fhdl.module import Module
+from migen.fhdl.specials import Instance
+from migen.genlib.io import DifferentialInput, DifferentialOutput
 
 
 class AlteraDifferentialInputImpl(Module):
index d5eda886f48e1b6ad62e42cc3e896938ded65bdc..011bd8053c09372ca232d7761196d1f9c33d806f 100644 (file)
@@ -4,7 +4,7 @@
 import os
 import subprocess
 
-from litex.gen.fhdl.structure import _Fragment
+from migen.fhdl.structure import _Fragment
 
 from litex.build.generic_platform import Pins, IOStandard, Misc
 from litex.build import tools
index f6320acc98e2d2b23ca97e02c25e80f9151fb274..0ef51d1e5f104a8637179b5b5d200ec0928fafb0 100644 (file)
@@ -1,9 +1,9 @@
 import os
 
-from litex.gen.fhdl.structure import Signal
-from litex.gen.genlib.record import Record
-from litex.gen.genlib.io import CRG
-from litex.gen.fhdl import verilog, edif
+from migen.fhdl.structure import Signal
+from migen.genlib.record import Record
+from migen.genlib.io import CRG
+from migen.fhdl import verilog, edif
 from litex.build import tools
 
 
index 52cf28d9a5b040c45170fa065a641fef649d9ff7..c25e8b90304c9dad6d594e93f13e8dac8bc84d46 100644 (file)
@@ -1,7 +1,7 @@
-from litex.gen.fhdl.module import Module
-from litex.gen.fhdl.specials import Instance
-from litex.gen.genlib.io import *
-from litex.gen.genlib.resetsync import AsyncResetSynchronizer
+from migen.fhdl.module import Module
+from migen.fhdl.specials import Instance
+from migen.genlib.io import *
+from migen.genlib.resetsync import AsyncResetSynchronizer
 
 
 class LatticeAsyncResetSynchronizerImpl(Module):
index cd169fdbcd159e924628c437e0774166c0e1605c..ac967654e43adeb8d1cf98a35ffce4d87b106157 100644 (file)
@@ -6,7 +6,7 @@ import sys
 import subprocess
 import shutil
 
-from litex.gen.fhdl.structure import _Fragment
+from migen.fhdl.structure import _Fragment
 
 from litex.build.generic_platform import *
 from litex.build import tools
index fb8e87102a84e34b19a1dec614e9aadb526d3554..ab54984fe85f9a801c7cd19c4d0812b07b6d36d4 100644 (file)
@@ -4,7 +4,7 @@
 import os
 import subprocess
 
-from litex.gen.fhdl.structure import _Fragment
+from migen.fhdl.structure import _Fragment
 from litex.build import tools
 from litex.build.generic_platform import *
 
index 69c1538466f247a0d983d5d366308ce64f3a8774..3b50b667d16fe082eef07f231362bb71816b11a6 100644 (file)
@@ -2,13 +2,13 @@ import os
 import sys
 from distutils.version import StrictVersion
 
-from litex.gen.fhdl.structure import *
-from litex.gen.fhdl.specials import Instance
-from litex.gen.fhdl.module import Module
-from litex.gen.fhdl.specials import SynthesisDirective
-from litex.gen.genlib.cdc import *
-from litex.gen.genlib.resetsync import AsyncResetSynchronizer
-from litex.gen.genlib.io import *
+from migen.fhdl.structure import *
+from migen.fhdl.specials import Instance
+from migen.fhdl.module import Module
+from migen.fhdl.specials import SynthesisDirective
+from migen.genlib.cdc import *
+from migen.genlib.resetsync import AsyncResetSynchronizer
+from migen.genlib.io import *
 
 from litex.build import tools
 
index 8efa5d7a137098ecb40c3cf2294c2bb227103b63..e8698e5e9df204aca2c49db071fa87c829336af9 100644 (file)
@@ -2,7 +2,7 @@ import os
 import subprocess
 import sys
 
-from litex.gen.fhdl.structure import _Fragment
+from migen.fhdl.structure import _Fragment
 from litex.build.generic_platform import *
 from litex.build import tools
 from litex.build.xilinx import common
index 18474d3d21ba1d6cecfc38edd1fcbcd2f9d65e21..3900fd8640be54ae8a241e59b416803ec3c3641d 100644 (file)
@@ -5,7 +5,7 @@ import os
 import subprocess
 import sys
 
-from litex.gen.fhdl.structure import _Fragment
+from migen.fhdl.structure import _Fragment
 from litex.build.generic_platform import *
 from litex.build import tools
 from litex.build.xilinx import common
diff --git a/litex/gen/MIGEN_LICENSE b/litex/gen/MIGEN_LICENSE
deleted file mode 100644 (file)
index 4f29060..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-Unless otherwise noted, Migen is copyright (C) 2011-2013 Sebastien Bourdeauducq.
-The simulation extension (as mentioned in the comments at the beginning of the
-corresponding source files) is copyright (C) 2012 Vermeer Manufacturing Co. All
-rights reserved.
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
-
-1. Redistributions of source code must retain the above copyright notice, this
-   list of conditions and the following disclaimer. 
-2. Redistributions in binary form must reproduce the above copyright notice,
-   this list of conditions and the following disclaimer in the documentation
-   and/or other materials provided with the distribution. 
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
-ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-
-Other authors retain ownership of their contributions. If a submission can
-reasonably be considered independently copyrightable, it's yours and we
-encourage you to claim it with appropriate copyright notices. This submission
-then falls under the "otherwise noted" category. All submissions are strongly
-encouraged to use the two-clause BSD license reproduced above.
index 264a79e20c6eb72b755fa9cbedd329266b59239e..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644 (file)
@@ -1,10 +0,0 @@
-from litex.gen.fhdl.structure import *
-from litex.gen.fhdl.module import *
-from litex.gen.fhdl.specials import *
-from litex.gen.fhdl.bitcontainer import *
-from litex.gen.fhdl.decorators import *
-
-from litex.gen.sim import *
-
-from litex.gen.genlib.record import *
-from litex.gen.genlib.fsm import *
diff --git a/litex/gen/fhdl/__init__.py b/litex/gen/fhdl/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/litex/gen/fhdl/bitcontainer.py b/litex/gen/fhdl/bitcontainer.py
deleted file mode 100644 (file)
index 11a3ede..0000000
+++ /dev/null
@@ -1,121 +0,0 @@
-from litex.gen.fhdl import structure as f
-
-
-__all__ = ["log2_int", "bits_for", "value_bits_sign"]
-
-
-def log2_int(n, need_pow2=True):
-    l = 1
-    r = 0
-    while l < n:
-        l *= 2
-        r += 1
-    if need_pow2 and l != n:
-        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)
-    else:
-        require_sign_bit = True
-        r = log2_int(-n, False)
-    if require_sign_bit:
-        r += 1
-    return r
-
-
-def value_bits_sign(v):
-    """Bit length and signedness of a value.
-
-    Parameters
-    ----------
-    v : Value
-
-    Returns
-    -------
-    int, bool
-        Number of bits required to store `v` or available in `v`, followed by
-        whether `v` has a sign bit (included in the bit count).
-
-    Examples
-    --------
-    >>> value_bits_sign(f.Signal(8))
-    8, False
-    >>> value_bits_sign(C(0xaa))
-    8, False
-    """
-    if isinstance(v, (f.Constant, f.Signal)):
-        return v.nbits, v.signed
-    elif isinstance(v, (f.ClockSignal, f.ResetSignal)):
-        return 1, False
-    elif isinstance(v, f._Operator):
-        obs = list(map(value_bits_sign, v.operands))
-        if v.op == "+" or v.op == "-":
-            if not obs[0][1] and not obs[1][1]:
-                # both operands unsigned
-                return max(obs[0][0], obs[1][0]) + 1, False
-            elif obs[0][1] and obs[1][1]:
-                # both operands signed
-                return max(obs[0][0], obs[1][0]) + 1, True
-            elif not obs[0][1] and obs[1][1]:
-                # first operand unsigned (add sign bit), second operand signed
-                return max(obs[0][0] + 1, obs[1][0]) + 1, True
-            else:
-                # first signed, second operand unsigned (add sign bit)
-                return max(obs[0][0], obs[1][0] + 1) + 1, True
-        elif v.op == "*":
-            if not obs[0][1] and not obs[1][1]:
-                # both operands unsigned
-                return obs[0][0] + obs[1][0], False
-            elif obs[0][1] and obs[1][1]:
-                # both operands signed
-                return obs[0][0] + obs[1][0] - 1, True
-            else:
-                # one operand signed, the other unsigned (add sign bit)
-                return obs[0][0] + obs[1][0] + 1 - 1, True
-        elif v.op == "<<<":
-            if obs[1][1]:
-                extra = 2**(obs[1][0] - 1) - 1
-            else:
-                extra = 2**obs[1][0] - 1
-            return obs[0][0] + extra, obs[0][1]
-        elif v.op == ">>>":
-            if obs[1][1]:
-                extra = 2**(obs[1][0] - 1)
-            else:
-                extra = 0
-            return obs[0][0] + extra, obs[0][1]
-        elif v.op == "&" or v.op == "^" or v.op == "|":
-            if not obs[0][1] and not obs[1][1]:
-                # both operands unsigned
-                return max(obs[0][0], obs[1][0]), False
-            elif obs[0][1] and obs[1][1]:
-                # both operands signed
-                return max(obs[0][0], obs[1][0]), True
-            elif not obs[0][1] and obs[1][1]:
-                # first operand unsigned (add sign bit), second operand signed
-                return max(obs[0][0] + 1, obs[1][0]), True
-            else:
-                # first signed, second operand unsigned (add sign bit)
-                return max(obs[0][0], obs[1][0] + 1), True
-        elif v.op == "<" or v.op == "<=" or v.op == "==" or v.op == "!=" \
-          or v.op == ">" or v.op == ">=":
-              return 1, False
-        elif v.op == "~":
-            return obs[0]
-        else:
-            raise TypeError
-    elif isinstance(v, f._Slice):
-        return v.stop - v.start, value_bits_sign(v.value)[1]
-    elif isinstance(v, f.Cat):
-        return sum(value_bits_sign(sv)[0] for sv in v.l), False
-    elif isinstance(v, f.Replicate):
-        return (value_bits_sign(v.v)[0])*v.n, False
-    elif isinstance(v, f._ArrayProxy):
-        bsc = list(map(value_bits_sign, v.choices))
-        return max(bs[0] for bs in bsc), any(bs[1] for bs in bsc)
-    else:
-        raise TypeError("Can not calculate bit length of {} {}".format(
-            type(v), v))
diff --git a/litex/gen/fhdl/conv_output.py b/litex/gen/fhdl/conv_output.py
deleted file mode 100644 (file)
index 793fad2..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-from operator import itemgetter
-
-
-class ConvOutput:
-    def __init__(self):
-        self.main_source = ""
-        self.data_files = dict()
-
-    def set_main_source(self, src):
-        self.main_source = src
-
-    def add_data_file(self, filename_base, content):
-        filename = filename_base
-        i = 1
-        while filename in self.data_files:
-            parts = filename_base.split(".", maxsplit=1)
-            parts[0] += "_" + str(i)
-            filename = ".".join(parts)
-            i += 1
-        self.data_files[filename] = content
-        return filename
-
-    def __str__(self):
-        r = self.main_source + "\n"
-        for filename, content in sorted(self.data_files.items(),
-                                        key=itemgetter(0)):
-            r += filename + ":\n" + content
-        return r
-
-    def write(self, main_filename):
-        with open(main_filename, "w") as f:
-            f.write(self.main_source)
-        for filename, content in self.data_files.items():
-            with open(filename, "w") as f:
-                f.write(content)
diff --git a/litex/gen/fhdl/decorators.py b/litex/gen/fhdl/decorators.py
deleted file mode 100644 (file)
index 59444ea..0000000
+++ /dev/null
@@ -1,107 +0,0 @@
-from litex.gen.fhdl.structure import *
-from litex.gen.fhdl.module import Module
-from litex.gen.fhdl.tools import insert_reset, rename_clock_domain
-
-
-__all__ = ["CEInserter", "ResetInserter", "ClockDomainsRenamer",
-           "ModuleTransformer"]
-
-
-class ModuleTransformer:
-    # overload this in derived classes
-    def transform_instance(self, i):
-        pass
-
-    # overload this in derived classes
-    def transform_fragment(self, i, f):
-        pass
-
-    def wrap_class(self, victim):
-        class Wrapped(victim):
-            def __init__(i, *args, **kwargs):
-                victim.__init__(i, *args, **kwargs)
-                self.transform_instance(i)
-
-            def get_fragment(i):
-                f = victim.get_fragment(i)
-                self.transform_fragment(i, f)
-                return f
-
-        Wrapped.__name__ = victim.__name__
-        # "{}_{}".format(self.__class__.__name__, victim.__name__)
-        return Wrapped
-
-    def wrap_instance(self, victim):
-        self.transform_instance(victim)
-        orig_get_fragment = victim.get_fragment
-
-        def get_fragment():
-            f = orig_get_fragment()
-            self.transform_fragment(victim, f)
-            return f
-
-        victim.get_fragment = get_fragment
-        return victim
-
-    def __call__(self, victim):
-        if isinstance(victim, Module):
-            return self.wrap_instance(victim)
-        else:
-            return self.wrap_class(victim)
-
-
-class ControlInserter(ModuleTransformer):
-    control_name = None  # override this
-
-    def __init__(self, clock_domains=None):
-        self.clock_domains = clock_domains
-
-    def transform_instance(self, i):
-        if self.clock_domains is None:
-            ctl = Signal(name=self.control_name)
-            assert not hasattr(i, self.control_name)
-            setattr(i, self.control_name, ctl)
-        else:
-            for cd in self.clock_domains:
-                name = self.control_name + "_" + cd
-                ctl = Signal(name=name)
-                assert not hasattr(i, name)
-                setattr(i, name, ctl)
-
-    def transform_fragment(self, i, f):
-        if self.clock_domains is None:
-            if len(f.sync) != 1:
-                raise ValueError("Control signal clock domains must be specified when module has more than one domain")
-            cdn = list(f.sync.keys())[0]
-            to_insert = [(getattr(i, self.control_name), cdn)]
-        else:
-            to_insert = [(getattr(i, self.control_name + "_" + cdn), cdn)
-                for cdn in self.clock_domains]
-        self.transform_fragment_insert(i, f, to_insert)
-
-
-class CEInserter(ControlInserter):
-    control_name = "ce"
-
-    def transform_fragment_insert(self, i, f, to_insert):
-        for ce, cdn in to_insert:
-            f.sync[cdn] = [If(ce, *f.sync[cdn])]
-
-
-class ResetInserter(ControlInserter):
-    control_name = "reset"
-
-    def transform_fragment_insert(self, i, f, to_insert):
-        for reset, cdn in to_insert:
-            f.sync[cdn] = insert_reset(reset, f.sync[cdn])
-
-
-class ClockDomainsRenamer(ModuleTransformer):
-    def __init__(self, cd_remapping):
-        if isinstance(cd_remapping, str):
-            cd_remapping = {"sys": cd_remapping}
-        self.cd_remapping = cd_remapping
-
-    def transform_fragment(self, i, f):
-        for old, new in self.cd_remapping.items():
-            rename_clock_domain(f, old, new)
diff --git a/litex/gen/fhdl/edif.py b/litex/gen/fhdl/edif.py
deleted file mode 100644 (file)
index f68c99b..0000000
+++ /dev/null
@@ -1,213 +0,0 @@
-from collections import OrderedDict, namedtuple
-
-from litex.gen.fhdl.structure import *
-from litex.gen.fhdl.namer import build_namespace
-from litex.gen.fhdl.tools import list_special_ios
-from litex.gen.fhdl.structure import _Fragment
-from litex.gen.fhdl.conv_output import ConvOutput
-
-
-_Port = namedtuple("_Port", "name direction")
-_Cell = namedtuple("_Cell", "name ports")
-_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:
-        r += """
-        (cell {0.name}
-            (cellType GENERIC)
-                (view view_1
-                    (viewType NETLIST)
-                    (interface""".format(cell)
-        for port in cell.ports:
-            r += """
-                        (port {0.name} (direction {0.direction}))""".format(port)
-        r += """
-                    )
-                )
-        )"""
-    return r
-
-
-def _write_io(ios):
-    r = ""
-    for s in ios:
-        r += """
-                        (port {0.name} (direction {0.direction}))""".format(s)
-    return r
-
-
-def _write_instantiations(instances, cell_library):
-    instantiations = ""
-    for instance in instances:
-        instantiations += """
-                        (instance {0.name}
-                            (viewRef view_1 (cellRef {0.cell} (libraryRef {1})))""".format(instance, cell_library)
-        for prop in instance.properties:
-            instantiations += """
-                            (property {0} (string "{1}"))""".format(prop.name, prop.value)
-        instantiations += """
-                        )"""
-    return instantiations
-
-
-def _write_connections(connections):
-    r = ""
-    for netname, branches in connections.items():
-        r += """
-                        (net {0}
-                            (joined""".format(netname)
-        for branch in branches:
-            r += """
-                                (portRef {0}{1})""".format(branch.portname, "" if branch.instancename == "" else " (instanceRef {})".format(branch.instancename))
-        r += """
-                            )
-                        )"""
-    return r
-
-
-def _write_edif(cells, ios, instances, connections, cell_library, design_name, part, vendor):
-    r = """(edif {0}
-    (edifVersion 2 0 0)
-    (edifLevel 0)
-    (keywordMap (keywordLevel 0))
-    (external {1}
-        (edifLevel 0)
-        (technology (numberDefinition))""".format(design_name, cell_library)
-    r += _write_cells(cells)
-    r += """
-    )
-    (library {0}_lib
-        (edifLevel 0)
-        (technology (numberDefinition))
-        (cell {0}
-            (cellType GENERIC)
-                (view view_1
-                    (viewType NETLIST)
-                    (interface""".format(design_name)
-    r += _write_io(ios)
-    r += """
-                        (designator "{0}")
-                    )
-                    (contents""".format(part)
-    r += _write_instantiations(instances, cell_library)
-    r += _write_connections(connections)
-    r += """
-                    )
-                )
-        )
-    )
-    (design {0}
-        (cellRef {0} (libraryRef {0}_lib))
-        (property PART (string "{1}") (owner "{2}"))
-    )
-)""".format(design_name, part, vendor)
-
-    return r
-
-
-def _generate_cells(f):
-    cell_dict = OrderedDict()
-    for special in f.specials:
-        if isinstance(special, Instance):
-            port_list = []
-            for port in special.items:
-                if isinstance(port, Instance.Input):
-                    port_list.append(_Port(port.name, "INPUT"))
-                elif isinstance(port, Instance.Output):
-                    port_list.append(_Port(port.name, "OUTPUT"))
-                elif isinstance(port, Instance.InOut):
-                    port_list.append(_Port(port.name, "INOUT"))
-                elif isinstance(port, Instance.Parameter):
-                    pass
-                else:
-                    raise NotImplementedError("Unsupported instance item")
-            if special.of in cell_dict:
-                if set(port_list) != set(cell_dict[special.of]):
-                    raise ValueError("All instances must have the same ports for EDIF conversion")
-            else:
-                cell_dict[special.of] = port_list
-        else:
-            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:
-        if isinstance(special, Instance):
-            props = []
-            for prop in special.items:
-                if isinstance(prop, Instance.Input):
-                    pass
-                elif isinstance(prop, Instance.Output):
-                    pass
-                elif isinstance(prop, Instance.InOut):
-                    pass
-                elif isinstance(prop, Instance.Parameter):
-                    props.append(_Property(name=prop.name, value=prop.value))
-                else:
-                    raise NotImplementedError("Unsupported instance item")
-            instances.append(_Instance(name=ns.get_name(special), cell=special.of, properties=props))
-        else:
-            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)
-    r = []
-    for io in ios:
-        direction = "OUTPUT" if io in outs else "INOUT" if io in inouts else "INPUT"
-        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:
-        if isinstance(special, Instance):
-            instname = ns.get_name(special)
-            for port in special.items:
-                if isinstance(port, Instance._IO):
-                    s = ns.get_name(port.expr)
-                    if s not in r:
-                        r[s] = []
-                    r[s].append(_NetBranch(portname=port.name, instancename=instname))
-                elif isinstance(port, Instance.Parameter):
-                    pass
-                else:
-                    raise NotImplementedError("Unsupported instance item")
-        else:
-            raise ValueError("EDIF conversion can only handle synthesized fragments")
-    for s in ios:
-        io = ns.get_name(s)
-        if io not in r:
-            r[io] = []
-        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()
-    if f.comb != [] or f.sync != {}:
-        raise ValueError("EDIF conversion can only handle synthesized fragments")
-    if ios is None:
-        ios = set()
-    cells = _generate_cells(f)
-    ns = build_namespace(list_special_ios(f, True, True, True))
-    instances = _generate_instances(f, ns)
-    inouts = _generate_ios(f, ios, ns)
-    connections = _generate_connections(f, ios, ns)
-    src = _write_edif(cells, inouts, instances, connections, cell_library, name, device, vendor)
-
-    r = ConvOutput()
-    r.set_main_source(src)
-    r.ns = ns
-    return r
diff --git a/litex/gen/fhdl/module.py b/litex/gen/fhdl/module.py
deleted file mode 100644 (file)
index a860751..0000000
+++ /dev/null
@@ -1,185 +0,0 @@
-import collections
-from itertools import combinations
-
-from litex.gen.util.misc import flat_iteration
-from litex.gen.fhdl.structure import *
-from litex.gen.fhdl.structure import _Fragment
-from litex.gen.fhdl.tools import rename_clock_domain
-
-
-__all__ = ["Module", "FinalizeError"]
-
-
-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]
-    except KeyError:
-        l = []
-        d[key] = l
-    l += _flat_list(statements)
-
-
-class _ModuleSyncCD:
-    def __init__(self, fm, cd):
-        self._fm = fm
-        self._cd = cd
-
-    def __iadd__(self, other):
-        _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)
-        return self
-
-    def __getattr__(self, name):
-        return _ModuleSyncCD(self._fm, name)
-
-    def __setattr__(self, name, value):
-        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.
-class _ModuleForwardAttr:
-    def __setattr__(self, name, value):
-        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)]
-        setattr(self._fm, name, value)
-
-    def __iadd__(self, other):
-        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)
-        self.get_fragment_called = True
-        self.finalize()
-        return self._fragment
-
-    def __getattr__(self, name):
-        if name == "comb":
-            return _ModuleComb(self)
-        elif name == "sync":
-            return _ModuleSync(self)
-        elif name == "specials":
-            return _ModuleSpecials(self)
-        elif name == "submodules":
-            return _ModuleSubmodules(self)
-        elif name == "clock_domains":
-            return _ModuleClockDomains(self)
-
-        # hack to have initialized regular attributes without using __init__
-        # (which would require derived classes to call it)
-        elif name == "finalized":
-            self.finalized = False
-            return self.finalized
-        elif name == "_fragment":
-            self._fragment = _Fragment()
-            return self._fragment
-        elif name == "_submodules":
-            self._submodules = []
-            return self._submodules
-        elif name == "_clock_domains":
-            self._clock_domains = []
-            return self._clock_domains
-        elif name == "get_fragment_called":
-            self.get_fragment_called = False
-            return self.get_fragment_called
-
-        else:
-            raise AttributeError("'"+self.__class__.__name__+"' object has no attribute '"+name+"'")
-
-    def __setattr__(self, name, value):
-        if name in ["comb", "sync", "specials", "submodules", "clock_domains"]:
-            if not isinstance(value, _ModuleProxy):
-                raise AttributeError("Attempted to assign special Module property - use += instead")
-        else:
-            object.__setattr__(self, name, value)
-
-    def _collect_submodules(self):
-        r = []
-        for name, submodule in self._submodules:
-            if not submodule.get_fragment_called:
-                r.append((name, submodule.get_fragment()))
-        return r
-
-    def finalize(self, *args, **kwargs):
-        if not self.finalized:
-            self.finalized = True
-            # finalize existing submodules before finalizing us
-            subfragments = self._collect_submodules()
-            self.do_finalize(*args, **kwargs)
-            # finalize submodules created by do_finalize
-            subfragments += self._collect_submodules()
-            # resolve clock domain name conflicts
-            needs_renaming = set()
-            for (mod_name1, f1), (mod_name2, f2) in combinations(subfragments, 2):
-                f1_names = set(cd.name for cd in f1.clock_domains)
-                f2_names = set(cd.name for cd in f2.clock_domains)
-                common_names = f1_names & f2_names
-                if common_names:
-                    if mod_name1 is None or mod_name2 is None:
-                        raise ValueError("Multiple submodules with local clock domains cannot be anonymous")
-                    if mod_name1 == mod_name2:
-                        raise ValueError("Multiple submodules with local clock domains cannot have the same name")
-                needs_renaming |= common_names
-            for mod_name, f in subfragments:
-                for cd in f.clock_domains:
-                    if cd.name in needs_renaming:
-                        rename_clock_domain(f, cd.name, mod_name + "_" + cd.name)
-            # sum subfragments
-            for mod_name, f in subfragments:
-                self._fragment += f
-
-    def do_finalize(self):
-        pass
-
-    def do_exit(self, *args, **kwargs):
-        for name, submodule in self._submodules:
-            submodule.do_exit(*args, **kwargs)
diff --git a/litex/gen/fhdl/namer.py b/litex/gen/fhdl/namer.py
deleted file mode 100644 (file)
index 5e8ecdd..0000000
+++ /dev/null
@@ -1,258 +0,0 @@
-from collections import OrderedDict
-from itertools import combinations
-
-from litex.gen.fhdl.structure import *
-
-
-class _Node:
-    def __init__(self):
-        self.signal_count = 0
-        self.numbers = set()
-        self.use_name = False
-        self.use_number = False
-        self.children = OrderedDict()
-
-
-def _display_tree(filename, tree):
-    from litex.gen.util.treeviz import RenderNode
-
-    def _to_render_node(name, node):
-        children = [_to_render_node(k, v) for k, v in node.children.items()]
-        if node.use_name:
-            if node.use_number:
-                color = (0.5, 0.9, 0.8)
-            else:
-                color = (0.8, 0.5, 0.9)
-        else:
-            if node.use_number:
-                color = (0.9, 0.8, 0.5)
-            else:
-                color = (0.8, 0.8, 0.8)
-        label = "{0}\n{1} signals\n{2}".format(name, node.signal_count, node.numbers)
-        return RenderNode(label, children, color=color)
-
-    top = _to_render_node("top", tree)
-    top.to_svg(filename)
-
-
-def _build_tree(signals, basic_tree=None):
-    root = _Node()
-    for signal in signals:
-        current_b = basic_tree
-        current = root
-        current.signal_count += 1
-        for name, number in signal.backtrace:
-            if basic_tree is None:
-                use_number = False
-            else:
-                current_b = current_b.children[name]
-                use_number = current_b.use_number
-            if use_number:
-                key = (name, number)
-            else:
-                key = name
-            try:
-                current = current.children[key]
-            except KeyError:
-                new = _Node()
-                current.children[key] = new
-                current = new
-            current.numbers.add(number)
-            if use_number:
-                current.all_numbers = sorted(current_b.numbers)
-            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):
-        if not c1_names.isdisjoint(c2_names):
-            node.children[c1_prefix].use_name = True
-            node.children[c2_prefix].use_name = True
-    r = set()
-    for c_prefix, c_names in cnames:
-        if node.children[c_prefix].use_name:
-            for c_name in c_names:
-                r.add((c_prefix, ) + c_name)
-        else:
-            r |= c_names
-
-    if node.signal_count > sum(c.signal_count for c in node.children.values()):
-        node.use_name = True
-        r.add((node_name, ))
-
-    return r
-
-
-def _name_signal(tree, signal):
-    elements = []
-    treepos = tree
-    for step_name, step_n in signal.backtrace:
-        try:
-            treepos = treepos.children[(step_name, step_n)]
-            use_number = True
-        except KeyError:
-            treepos = treepos.children[step_name]
-            use_number = False
-        if treepos.use_name:
-            elname = step_name
-            if use_number:
-                elname += str(treepos.all_numbers.index(step_n))
-            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():
-        inv_pnd[v] = inv_pnd.get(v, [])
-        inv_pnd[v].append(k)
-    return inv_pnd
-
-
-def _list_conflicting_signals(pnd):
-    inv_pnd = _invert_pnd(pnd)
-    r = set()
-    for k, v in inv_pnd.items():
-        if len(v) > 1:
-            r.update(v)
-    return r
-
-
-def _set_use_number(tree, signals):
-    for signal in signals:
-        current = tree
-        for step_name, step_n in signal.backtrace:
-            current = current.children[step_name]
-            current.use_number = current.signal_count > len(current.numbers) and len(current.numbers) > 1
-
-_debug = False
-
-
-def _build_pnd_for_group(group_n, signals):
-    basic_tree = _build_tree(signals)
-    _set_use_name(basic_tree)
-    if _debug:
-        _display_tree("tree{0}_basic.svg".format(group_n), basic_tree)
-    pnd = _build_pnd_from_tree(basic_tree, signals)
-
-    # If there are conflicts, try splitting the tree by numbers
-    # on paths taken by conflicting signals.
-    conflicting_signals = _list_conflicting_signals(pnd)
-    if conflicting_signals:
-        _set_use_number(basic_tree, conflicting_signals)
-        if _debug:
-            print("namer: using split-by-number strategy (group {0})".format(group_n))
-            _display_tree("tree{0}_marked.svg".format(group_n), basic_tree)
-        numbered_tree = _build_tree(signals, basic_tree)
-        _set_use_name(numbered_tree)
-        if _debug:
-            _display_tree("tree{0}_numbered.svg".format(group_n), numbered_tree)
-        pnd = _build_pnd_from_tree(numbered_tree, signals)
-    else:
-        if _debug:
-            print("namer: using basic strategy (group {0})".format(group_n))
-
-    # ...then add number suffixes by DUID
-    inv_pnd = _invert_pnd(pnd)
-    duid_suffixed = False
-    for name, signals in inv_pnd.items():
-        if len(signals) > 1:
-            duid_suffixed = True
-            for n, signal in enumerate(sorted(signals, key=lambda x: x.duid)):
-                pnd[signal] += str(n)
-    if _debug and duid_suffixed:
-        print("namer: using DUID suffixes (group {0})".format(group_n))
-
-    return pnd
-
-
-def _build_signal_groups(signals):
-    r = []
-    for signal in signals:
-        # build chain of related signals
-        related_list = []
-        cur_signal = signal
-        while cur_signal is not None:
-            related_list.insert(0, cur_signal)
-            cur_signal = cur_signal.related
-        # add to groups
-        for _ in range(len(related_list) - len(r)):
-            r.append(set())
-        for target_set, source_signal in zip(r, related_list):
-            target_set.add(source_signal)
-    # with the algorithm above and a list of all signals,
-    # a signal appears in all groups of a lower number than its.
-    # make signals appear only in their group of highest number.
-    for s1, s2 in zip(r, r[1:]):
-        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)]
-
-    pnd = dict()
-    for gn, gpnd in enumerate(gpnds):
-        for signal, name in gpnd.items():
-            result = name
-            cur_gn = gn
-            cur_signal = signal
-            while cur_signal.related is not None:
-                cur_signal = cur_signal.related
-                cur_gn -= 1
-                result = gpnds[cur_gn][cur_signal] + "_" + result
-            pnd[signal] = result
-
-    return pnd
-
-
-def build_namespace(signals, reserved_keywords=set()):
-    pnd = _build_pnd(signals)
-    ns = Namespace(pnd, reserved_keywords)
-    # register signals with name_override
-    for signal in signals:
-        if signal.name_override is not None:
-            ns.get_name(signal)
-    return ns
-
-
-class Namespace:
-    def __init__(self, pnd, reserved_keywords=set()):
-        self.counts = {k: 1 for k in reserved_keywords}
-        self.sigs = {}
-        self.pnd = pnd
-        self.clock_domains = dict()
-
-    def get_name(self, sig):
-        if isinstance(sig, ClockSignal):
-            sig = self.clock_domains[sig.cd].clk
-        if isinstance(sig, ResetSignal):
-            sig = self.clock_domains[sig.cd].rst
-            if sig is None:
-                raise ValueError("Attempted to obtain name of non-existent "
-                                 "reset signal of domain "+sig.cd)
-
-        if sig.name_override is not None:
-            sig_name = sig.name_override
-        else:
-            sig_name = self.pnd[sig]
-        try:
-            n = self.sigs[sig]
-        except KeyError:
-            try:
-                n = self.counts[sig_name]
-            except KeyError:
-                n = 0
-            self.sigs[sig] = n
-            self.counts[sig_name] = n + 1
-        if n:
-            return sig_name + "_" + str(n)
-        else:
-            return sig_name
diff --git a/litex/gen/fhdl/simplify.py b/litex/gen/fhdl/simplify.py
deleted file mode 100644 (file)
index 747f562..0000000
+++ /dev/null
@@ -1,114 +0,0 @@
-from litex.gen.fhdl.structure import *
-from litex.gen.fhdl.specials import Memory, _MemoryPort, WRITE_FIRST, NO_CHANGE
-from litex.gen.fhdl.decorators import ModuleTransformer
-from litex.gen.util.misc import gcd_multiple
-
-
-class FullMemoryWE(ModuleTransformer):
-    def __init__(self):
-        self.replacments = dict()
-
-    def transform_fragment(self, i, f):
-        newspecials = set()
-
-        for orig in f.specials:
-            if not isinstance(orig, Memory):
-                newspecials.add(orig)
-                continue
-            global_granularity = gcd_multiple([p.we_granularity if p.we_granularity else orig.width for p in orig.ports])
-            if global_granularity == orig.width:
-                newspecials.add(orig)  # nothing to do
-            else:
-                newmems = []
-                for i in range(orig.width//global_granularity):
-                    if orig.init is None:
-                        newinit = None
-                    else:
-                        newinit = [(v >> i*global_granularity) & (2**global_granularity - 1) for v in orig.init]
-                    newmem = Memory(global_granularity, orig.depth, newinit, orig.name_override + "_grain" + str(i))
-                    newspecials.add(newmem)
-                    newmems.append(newmem)
-                    for port in orig.ports:
-                        port_granularity = port.we_granularity if port.we_granularity else orig.width
-                        newport = _MemoryPort(
-                            adr=port.adr,
-
-                            dat_r=port.dat_r[i*global_granularity:(i+1)*global_granularity] if port.dat_r is not None else None,
-                            we=port.we[i*global_granularity//port_granularity] if port.we is not None else None,
-                            dat_w=port.dat_w[i*global_granularity:(i+1)*global_granularity] if port.dat_w is not None else None,
-
-                            async_read=port.async_read,
-                            re=port.re,
-                            we_granularity=0,
-                            mode=port.mode,
-                            clock_domain=port.clock.cd)
-                        newmem.ports.append(newport)
-                        newspecials.add(newport)
-                self.replacments[orig] = newmems
-
-        f.specials = newspecials
-
-
-class MemoryToArray(ModuleTransformer):
-    def __init__(self):
-        self.replacements = dict()
-
-    def transform_fragment(self, i, f):
-        newspecials = set()
-
-        for mem in f.specials:
-            if not isinstance(mem, Memory):
-                newspecials.add(mem)
-                continue
-
-            storage = Array()
-            self.replacements[mem] = storage
-            init = []
-            if mem.init is not None:
-                init = mem.init
-            for d in init:
-                mem_storage = Signal(mem.width, reset=d)
-                storage.append(mem_storage)
-            for _ in range(mem.depth-len(init)):
-                mem_storage = Signal(mem.width)
-                storage.append(mem_storage)
-
-            for port in mem.ports:
-                if port.we_granularity:
-                    raise NotImplementedError
-                try:
-                    sync = f.sync[port.clock.cd]
-                except KeyError:
-                    sync = f.sync[port.clock.cd] = []
-
-                # read
-                if port.async_read:
-                    f.comb.append(port.dat_r.eq(storage[port.adr]))
-                else:
-                    if port.mode == WRITE_FIRST and port.we is not None:
-                        adr_reg = Signal.like(port.adr)
-                        rd_stmt = adr_reg.eq(port.adr)
-                        f.comb.append(port.dat_r.eq(storage[adr_reg]))
-                    elif port.mode == NO_CHANGE and port.we is not None:
-                        rd_stmt = If(~port.we, port.dat_r.eq(storage[port.adr]))
-                    else: # READ_FIRST or port.we is None, simplest case
-                        rd_stmt = port.dat_r.eq(storage[port.adr])
-                    if port.re is None:
-                        sync.append(rd_stmt)
-                    else:
-                        sync.append(If(port.re, rd_stmt))
-
-                # write
-                if port.we is not None:
-                    if port.we_granularity:
-                        n = mem.width//port.we_granularity
-                        for i in range(n):
-                            m = i*port.we_granularity
-                            M = (i+1)*port.we_granularity
-                            sync.append(If(port.we[i],
-                                        storage[port.adr][m:M].eq(port.dat_w)))
-                    else:
-                        sync.append(If(port.we,
-                                       storage[port.adr].eq(port.dat_w)))
-
-        f.specials = newspecials
diff --git a/litex/gen/fhdl/specials.py b/litex/gen/fhdl/specials.py
deleted file mode 100644 (file)
index d4fc2bf..0000000
+++ /dev/null
@@ -1,360 +0,0 @@
-from operator import itemgetter
-
-from litex.gen.fhdl.structure import *
-from litex.gen.fhdl.structure import _Value
-from litex.gen.fhdl.bitcontainer import bits_for, value_bits_sign
-from litex.gen.fhdl.tools import *
-from litex.gen.fhdl.tracer import get_obj_var_name
-from litex.gen.fhdl.verilog import _printexpr as verilog_printexpr
-
-
-__all__ = ["TSTriple", "Instance", "Memory",
-    "READ_FIRST", "WRITE_FIRST", "NO_CHANGE"]
-
-
-class Special(DUID):
-    def iter_expressions(self):
-        for x in []:
-            yield x
-
-    def rename_clock_domain(self, old, new):
-        for obj, attr, direction in self.iter_expressions():
-            rename_clock_domain_expr(getattr(obj, attr), old, new)
-
-    def list_clock_domains(self):
-        r = set()
-        for obj, attr, direction in self.iter_expressions():
-            r |= list_clock_domains_expr(getattr(obj, attr))
-        return r
-
-    def list_ios(self, ins, outs, inouts):
-        r = set()
-        for obj, attr, direction in self.iter_expressions():
-            if (direction == SPECIAL_INPUT and ins) \
-              or (direction == SPECIAL_OUTPUT and outs) \
-              or (direction == SPECIAL_INOUT and inouts):
-                signals = list_signals(getattr(obj, attr))
-                r.update(signals)
-        return r
-
-
-class Tristate(Special):
-    def __init__(self, target, o, oe, i=None):
-        Special.__init__(self)
-        self.target = wrap(target)
-        self.o = wrap(o)
-        self.oe = wrap(oe)
-        self.i = wrap(i) if i is not None else None
-
-    def iter_expressions(self):
-        for attr, target_context in [
-          ("target", SPECIAL_INOUT),
-          ("o", SPECIAL_INPUT),
-          ("oe", SPECIAL_INPUT),
-          ("i", SPECIAL_OUTPUT)]:
-            if getattr(self, attr) is not None:
-                yield self, attr, target_context
-
-    @staticmethod
-    def emit_verilog(tristate, ns, add_data_file):
-        def pe(e):
-            return verilog_printexpr(ns, e)[0]
-        w, s = value_bits_sign(tristate.target)
-        r = "assign " + pe(tristate.target) + " = " \
-            + pe(tristate.oe) + " ? " + pe(tristate.o) \
-            + " : " + str(w) + "'bz;\n"
-        if tristate.i is not None:
-            r += "assign " + pe(tristate.i) + " = " + pe(tristate.target) + ";\n"
-        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)
-        self.oe = Signal(reset=reset_oe)
-        self.i = Signal(bits_sign, min=min, max=max)
-
-    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):
-            self.name = name
-            if expr is None:
-                expr = Signal()
-            self.expr = wrap(expr)
-    class Input(_IO):
-        pass
-    class Output(_IO):
-        pass
-    class InOut(_IO):
-        pass
-    class Parameter:
-        def __init__(self, name, value):
-            self.name = name
-            if isinstance(value, (int, bool)):
-                value = Constant(value)
-            self.value = value
-    class PreformattedParam(str):
-        pass
-
-    def __init__(self, of, *items, name="", synthesis_directive=None, **kwargs):
-        Special.__init__(self)
-        self.of = of
-        if name:
-            self.name_override = name
-        else:
-            self.name_override = of
-        self.items = list(items)
-        self.synthesis_directive = synthesis_directive
-        for k, v in sorted(kwargs.items(), key=itemgetter(0)):
-            item_type, item_name = k.split("_", maxsplit=1)
-            item_class = {
-                "i": Instance.Input,
-                "o": Instance.Output,
-                "io": Instance.InOut,
-                "p": Instance.Parameter
-            }[item_type]
-            self.items.append(item_class(item_name, v))
-
-    def get_io(self, name):
-        for item in self.items:
-            if isinstance(item, Instance._IO) and item.name == name:
-                return item.expr
-
-    def iter_expressions(self):
-        for item in self.items:
-            if isinstance(item, Instance.Input):
-                yield item, "expr", SPECIAL_INPUT
-            elif isinstance(item, Instance.Output):
-                yield item, "expr", SPECIAL_OUTPUT
-            elif isinstance(item, Instance.InOut):
-                yield item, "expr", SPECIAL_INOUT
-
-    @staticmethod
-    def emit_verilog(instance, ns, add_data_file):
-        r = instance.of + " "
-        parameters = list(filter(lambda i: isinstance(i, Instance.Parameter), instance.items))
-        if parameters:
-            r += "#(\n"
-            firstp = True
-            for p in parameters:
-                if not firstp:
-                    r += ",\n"
-                firstp = False
-                r += "\t." + p.name + "("
-                if isinstance(p.value, Constant):
-                    r += verilog_printexpr(ns, p.value)[0]
-                elif isinstance(p.value, float):
-                    r += str(p.value)
-                elif isinstance(p.value, Instance.PreformattedParam):
-                    r += p.value
-                elif isinstance(p.value, str):
-                    r += "\"" + p.value + "\""
-                else:
-                    raise TypeError
-                r += ")"
-            r += "\n) "
-        r += ns.get_name(instance)
-        if parameters: r += " "
-        r += "(\n"
-        firstp = True
-        for p in instance.items:
-            if isinstance(p, Instance._IO):
-                name_inst = p.name
-                name_design = verilog_printexpr(ns, p.expr)[0]
-                if not firstp:
-                    r += ",\n"
-                firstp = False
-                r += "\t." + name_inst + "(" + name_design + ")"
-        if not firstp:
-            r += "\n"
-        if instance.synthesis_directive is not None:
-            synthesis_directive = "/* synthesis {} */".format(instance.synthesis_directive)
-            r += ")" + synthesis_directive + ";\n\n"
-        else:
-            r += ");\n\n"
-        return r
-
-
-(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,
-      clock_domain="sys"):
-        Special.__init__(self)
-        self.adr = adr
-        self.dat_r = dat_r
-        self.we = we
-        self.dat_w = dat_w
-        self.async_read = async_read
-        self.re = re
-        self.we_granularity = we_granularity
-        self.mode = mode
-        self.clock = ClockSignal(clock_domain)
-
-    def iter_expressions(self):
-        for attr, target_context in [
-          ("adr", SPECIAL_INPUT),
-          ("we", SPECIAL_INPUT),
-          ("dat_w", SPECIAL_INPUT),
-          ("re", SPECIAL_INPUT),
-          ("dat_r", SPECIAL_OUTPUT),
-          ("clock", SPECIAL_INPUT)]:
-            yield self, attr, target_context
-
-    @staticmethod
-    def emit_verilog(port, ns, add_data_file):
-        return ""  # done by parent Memory object
-
-
-class _MemoryLocation(_Value):
-    def __init__(self, memory, index):
-        _Value.__init__(self)
-        self.memory = memory
-        self.index = wrap(index)
-
-
-class Memory(Special):
-    def __init__(self, width, depth, init=None, name=None):
-        Special.__init__(self)
-        self.width = width
-        self.depth = depth
-        self.ports = []
-        self.init = init
-        self.name_override = get_obj_var_name(name, "mem")
-
-    def __getitem__(self, index):
-        # simulation only
-        return _MemoryLocation(self, index)
-
-    def get_port(self, write_capable=False, async_read=False,
-      has_re=False, we_granularity=0, mode=WRITE_FIRST,
-      clock_domain="sys"):
-        if we_granularity >= self.width:
-            we_granularity = 0
-        adr = Signal(max=self.depth)
-        dat_r = Signal(self.width)
-        if write_capable:
-            if we_granularity:
-                we = Signal(self.width//we_granularity)
-            else:
-                we = Signal()
-            dat_w = Signal(self.width)
-        else:
-            we = None
-            dat_w = None
-        if has_re:
-            re = Signal()
-        else:
-            re = None
-        mp = _MemoryPort(adr, dat_r, we, dat_w,
-          async_read, re, we_granularity, mode,
-          clock_domain)
-        self.ports.append(mp)
-        return mp
-
-    @staticmethod
-    def emit_verilog(memory, ns, add_data_file):
-        r = ""
-        def gn(e):
-            if isinstance(e, Memory):
-                return ns.get_name(e)
-            else:
-                return verilog_printexpr(ns, e)[0]
-        adrbits = bits_for(memory.depth-1)
-
-        r += "reg [" + str(memory.width-1) + ":0] " \
-            + gn(memory) \
-            + "[0:" + str(memory.depth-1) + "];\n"
-
-        adr_regs = {}
-        data_regs = {}
-        for port in memory.ports:
-            if not port.async_read:
-                if port.mode == WRITE_FIRST and port.we is not None:
-                    adr_reg = Signal(name_override="memadr")
-                    r += "reg [" + str(adrbits-1) + ":0] " \
-                        + gn(adr_reg) + ";\n"
-                    adr_regs[id(port)] = adr_reg
-                else:
-                    data_reg = Signal(name_override="memdat")
-                    r += "reg [" + str(memory.width-1) + ":0] " \
-                        + gn(data_reg) + ";\n"
-                    data_regs[id(port)] = data_reg
-
-        for port in memory.ports:
-            r += "always @(posedge " + gn(port.clock) + ") begin\n"
-            if port.we is not None:
-                if port.we_granularity:
-                    n = memory.width//port.we_granularity
-                    for i in range(n):
-                        m = i*port.we_granularity
-                        M = (i+1)*port.we_granularity-1
-                        sl = "[" + str(M) + ":" + str(m) + "]"
-                        r += "\tif (" + gn(port.we) + "[" + str(i) + "])\n"
-                        r += "\t\t" + gn(memory) + "[" + gn(port.adr) + "]" + sl + " <= " + gn(port.dat_w) + sl + ";\n"
-                else:
-                    r += "\tif (" + gn(port.we) + ")\n"
-                    r += "\t\t" + gn(memory) + "[" + gn(port.adr) + "] <= " + gn(port.dat_w) + ";\n"
-            if not port.async_read:
-                if port.mode == WRITE_FIRST and port.we is not None:
-                    rd = "\t" + gn(adr_regs[id(port)]) + " <= " + gn(port.adr) + ";\n"
-                else:
-                    bassign = gn(data_regs[id(port)]) + " <= " + gn(memory) + "[" + gn(port.adr) + "];\n"
-                    if port.mode == READ_FIRST or port.we is None:
-                        rd = "\t" + bassign
-                    elif port.mode == NO_CHANGE:
-                        rd = "\tif (!" + gn(port.we) + ")\n" \
-                          + "\t\t" + bassign
-                if port.re is None:
-                    r += rd
-                else:
-                    r += "\tif (" + gn(port.re) + ")\n"
-                    r += "\t" + rd.replace("\n\t", "\n\t\t")
-            r += "end\n\n"
-
-        for port in memory.ports:
-            if port.async_read:
-                r += "assign " + gn(port.dat_r) + " = " + gn(memory) + "[" + gn(port.adr) + "];\n"
-            else:
-                if port.mode == WRITE_FIRST and port.we is not None:
-                    r += "assign " + gn(port.dat_r) + " = " + gn(memory) + "[" + gn(adr_regs[id(port)]) + "];\n"
-                else:
-                    r += "assign " + gn(port.dat_r) + " = " + gn(data_regs[id(port)]) + ";\n"
-        r += "\n"
-
-        if memory.init is not None:
-            content = ""
-            for d in memory.init:
-                content += "{:x}\n".format(d)
-            memory_filename = add_data_file(gn(memory) + ".init", content)
-
-            r += "initial begin\n"
-            r += "\t$readmemh(\"" + memory_filename + "\", " + gn(memory) + ");\n"
-            r += "end\n\n"
-
-        return r
-
-
-class SynthesisDirective(Special):
-    def __init__(self, template, **signals):
-        Special.__init__(self)
-        self.template = template
-        self.signals = signals
-
-    @staticmethod
-    def emit_verilog(directive, ns, add_data_file):
-        name_dict = dict((k, ns.get_name(sig)) for k, sig in directive.signals.items())
-        formatted = directive.template.format(**name_dict)
-        return "// synthesis " + formatted + "\n"
-
-
-class Keep(SynthesisDirective):
-    def __init__(self, signal):
-        SynthesisDirective.__init__(self, "attribute keep of {s} is true", s=signal)
diff --git a/litex/gen/fhdl/structure.py b/litex/gen/fhdl/structure.py
deleted file mode 100644 (file)
index 7e6d2ca..0000000
+++ /dev/null
@@ -1,713 +0,0 @@
-import builtins as _builtins
-import collections as _collections
-
-from litex.gen.fhdl import tracer as _tracer
-from litex.gen.util.misc import flat_iteration as _flat_iteration
-
-
-class DUID:
-    """Deterministic Unique IDentifier"""
-    __next_uid = 0
-    def __init__(self):
-        self.duid = DUID.__next_uid
-        DUID.__next_uid += 1
-
-
-class _Value(DUID):
-    """Base class for operands
-
-    Instances of `_Value` or its subclasses can be operands to
-    arithmetic, comparison, bitwise, and logic operators.
-    They can be assigned (:meth:`eq`) or indexed/sliced (using the usual
-    Python indexing and slicing notation).
-
-    Values created from integers have the minimum bit width to necessary to
-    represent the integer.
-    """
-    def __bool__(self):
-        # Special case: Constants and Signals are part of a set or used as
-        # dictionary keys, and Python needs to check for equality.
-        if isinstance(self, _Operator) and self.op == "==":
-            a, b = self.operands
-            if isinstance(a, Constant) and isinstance(b, Constant):
-                return a.value == b.value
-            if isinstance(a, Signal) and isinstance(b, Signal):
-                return a is b
-            if (isinstance(a, Constant) and isinstance(b, Signal)
-                    or isinstance(a, Signal) and isinstance(a, Constant)):
-                return False
-        raise TypeError("Attempted to convert Migen value to boolean")
-
-    def __invert__(self):
-        return _Operator("~", [self])
-    def __neg__(self):
-        return _Operator("-", [self])
-
-    def __add__(self, other):
-        return _Operator("+", [self, other])
-    def __radd__(self, other):
-        return _Operator("+", [other, self])
-    def __sub__(self, other):
-        return _Operator("-", [self, other])
-    def __rsub__(self, other):
-        return _Operator("-", [other, self])
-    def __mul__(self, other):
-        return _Operator("*", [self, other])
-    def __rmul__(self, other):
-        return _Operator("*", [other, self])
-    def __lshift__(self, other):
-        return _Operator("<<<", [self, other])
-    def __rlshift__(self, other):
-        return _Operator("<<<", [other, self])
-    def __rshift__(self, other):
-        return _Operator(">>>", [self, other])
-    def __rrshift__(self, other):
-        return _Operator(">>>", [other, self])
-    def __and__(self, other):
-        return _Operator("&", [self, other])
-    def __rand__(self, other):
-        return _Operator("&", [other, self])
-    def __xor__(self, other):
-        return _Operator("^", [self, other])
-    def __rxor__(self, other):
-        return _Operator("^", [other, self])
-    def __or__(self, other):
-        return _Operator("|", [self, other])
-    def __ror__(self, other):
-        return _Operator("|", [other, self])
-
-    def __lt__(self, other):
-        return _Operator("<", [self, other])
-    def __le__(self, other):
-        return _Operator("<=", [self, other])
-    def __eq__(self, other):
-        return _Operator("==", [self, other])
-    def __ne__(self, other):
-        return _Operator("!=", [self, other])
-    def __gt__(self, other):
-        return _Operator(">", [self, other])
-    def __ge__(self, other):
-        return _Operator(">=", [self, other])
-
-    def __len__(self):
-        from litex.gen.fhdl.bitcontainer import value_bits_sign
-        return value_bits_sign(self)[0]
-
-    def __getitem__(self, key):
-        n = len(self)
-        if isinstance(key, int):
-            if key >= n:
-                raise IndexError
-            if key < 0:
-                key += n
-            return _Slice(self, key, key+1)
-        elif isinstance(key, slice):
-            start, stop, step = key.indices(n)
-            if step != 1:
-                return Cat(self[i] for i in range(start, stop, step))
-            return _Slice(self, start, stop)
-        else:
-            raise TypeError
-
-    def eq(self, r):
-        """Assignment
-
-        Parameters
-        ----------
-        r : _Value, in
-            Value to be assigned.
-
-        Returns
-        -------
-        _Assign
-            Assignment statement that can be used in combinatorial or
-            synchronous context.
-        """
-        return _Assign(self, r)
-
-    def __hash__(self):
-        raise TypeError("unhashable type: '{}'".format(type(self).__name__))
-
-
-def wrap(value):
-    """Ensures that the passed object is a Migen value. Booleans and integers
-    are automatically wrapped into ``Constant``."""
-    if isinstance(value, (bool, int)):
-        value = Constant(value)
-    if not isinstance(value, _Value):
-        raise TypeError("Object is not a Migen value")
-    return value
-
-
-class _Operator(_Value):
-    def __init__(self, op, operands):
-        _Value.__init__(self)
-        self.op = op
-        self.operands = [wrap(o) for o in operands]
-
-
-def Mux(sel, val1, val0):
-    """Multiplex between two values
-
-    Parameters
-    ----------
-    sel : _Value(1), in
-        Selector.
-    val1 : _Value(N), in
-    val0 : _Value(N), in
-        Input values.
-
-    Returns
-    -------
-    _Value(N), out
-        Output `_Value`. If `sel` is asserted, the Mux returns
-        `val1`, else `val0`.
-    """
-    return _Operator("m", [sel, val1, val0])
-
-
-class _Slice(_Value):
-    def __init__(self, value, start, stop):
-        _Value.__init__(self)
-        if not isinstance(start, int) or not isinstance(stop, int):
-            raise TypeError("Slice boundaries must be integers")
-        self.value = wrap(value)
-        self.start = start
-        self.stop = stop
-
-
-class Cat(_Value):
-    """Concatenate values
-
-    Form a compound `_Value` from several smaller ones by concatenation.
-    The first argument occupies the lower bits of the result.
-    The return value can be used on either side of an assignment, that
-    is, the concatenated value can be used as an argument on the RHS or
-    as a target on the LHS. If it is used on the LHS, it must solely
-    consist of `Signal` s, slices of `Signal` s, and other concatenations
-    meeting these properties. The bit length of the return value is the sum of
-    the bit lengths of the arguments::
-
-        len(Cat(args)) == sum(len(arg) for arg in args)
-
-    Parameters
-    ----------
-    *args : _Values or iterables of _Values, inout
-        `_Value` s to be concatenated.
-
-    Returns
-    -------
-    Cat, inout
-        Resulting `_Value` obtained by concatentation.
-    """
-    def __init__(self, *args):
-        _Value.__init__(self)
-        self.l = [wrap(v) for v in _flat_iteration(args)]
-
-
-class Replicate(_Value):
-    """Replicate a value
-
-    An input value is replicated (repeated) several times
-    to be used on the RHS of assignments::
-
-        len(Replicate(s, n)) == len(s)*n
-
-    Parameters
-    ----------
-    v : _Value, in
-        Input value to be replicated.
-    n : int
-        Number of replications.
-
-    Returns
-    -------
-    Replicate, out
-        Replicated value.
-    """
-    def __init__(self, v, n):
-        _Value.__init__(self)
-        if not isinstance(n, int) or n < 0:
-            raise TypeError("Replication count must be a positive integer")
-        self.v = wrap(v)
-        self.n = n
-
-
-class Constant(_Value):
-    """A constant, HDL-literal integer `_Value`
-
-    Parameters
-    ----------
-    value : int
-    bits_sign : int or tuple or None
-        Either an integer `bits` or a tuple `(bits, signed)`
-        specifying the number of bits in this `Constant` and whether it is
-        signed (can represent negative values). `bits_sign` defaults
-        to the minimum width and signedness of `value`.
-    """
-    def __init__(self, value, bits_sign=None):
-        from litex.gen.fhdl.bitcontainer import bits_for
-
-        _Value.__init__(self)
-
-        self.value = int(value)
-        if bits_sign is None:
-            bits_sign = bits_for(self.value), self.value < 0
-        elif isinstance(bits_sign, int):
-            bits_sign = bits_sign, self.value < 0
-        self.nbits, self.signed = bits_sign
-        if not isinstance(self.nbits, int) or self.nbits <= 0:
-            raise TypeError("Width must be a strictly positive integer")
-
-    def __hash__(self):
-        return self.value
-
-
-C = Constant  # shorthand
-
-
-class Signal(_Value):
-    """A `_Value` that can change
-
-    The `Signal` object represents a value that is expected to change
-    in the circuit. It does exactly what Verilog's `wire` and
-    `reg` and VHDL's `signal` do.
-
-    A `Signal` can be indexed to access a subset of its bits. Negative
-    indices (`signal[-1]`) and the extended Python slicing notation
-    (`signal[start:stop:step]`) are supported.
-    The indices 0 and -1 are the least and most significant bits
-    respectively.
-
-    Parameters
-    ----------
-    bits_sign : int or tuple
-        Either an integer `bits` or a tuple `(bits, signed)`
-        specifying the number of bits in this `Signal` and whether it is
-        signed (can represent negative values). `signed` defaults to
-        `False`.
-    name : str or None
-        Name hint for this signal. If `None` (default) the name is
-        inferred from the variable name this `Signal` is assigned to.
-        Name collisions are automatically resolved by prepending
-        names of objects that contain this `Signal` and by
-        appending integer sequences.
-    variable : bool
-        Deprecated.
-    reset : int
-        Reset (synchronous) or default (combinatorial) value.
-        When this `Signal` is assigned to in synchronous context and the
-        corresponding clock domain is reset, the `Signal` assumes the
-        given value. When this `Signal` is unassigned in combinatorial
-        context (due to conditional assignments not being taken),
-        the `Signal` assumes its `reset` value. Defaults to 0.
-    name_override : str or None
-        Do not use the inferred name but the given one.
-    min : int or None
-    max : int or None
-        If `bits_sign` is `None`, the signal bit width and signedness are
-        determined by the integer range given by `min` (inclusive,
-        defaults to 0) and `max` (exclusive, defaults to 2).
-    related : Signal or None
-    """
-    def __init__(self, bits_sign=None, name=None, variable=False, reset=0, name_override=None, min=None, max=None, related=None):
-        from litex.gen.fhdl.bitcontainer import bits_for
-
-        _Value.__init__(self)
-
-        # determine number of bits and signedness
-        if bits_sign is None:
-            if min is None:
-                min = 0
-            if max is None:
-                max = 2
-            max -= 1  # make both bounds inclusive
-            assert(min < max)
-            self.signed = min < 0 or max < 0
-            self.nbits = _builtins.max(bits_for(min, self.signed), bits_for(max, self.signed))
-        else:
-            assert(min is None and max is None)
-            if isinstance(bits_sign, tuple):
-                self.nbits, self.signed = bits_sign
-            else:
-                self.nbits, self.signed = bits_sign, False
-        if not isinstance(self.nbits, int) or self.nbits <= 0:
-            raise ValueError("Signal width must be a strictly positive integer")
-
-        self.variable = variable  # deprecated
-        self.reset = reset
-        self.name_override = name_override
-        self.backtrace = _tracer.trace_back(name)
-        self.related = related
-
-    def __setattr__(self, k, v):
-        if k == "reset":
-            v = wrap(v)
-        _Value.__setattr__(self, k, v)
-
-    def __repr__(self):
-        return "<Signal " + (self.backtrace[-1][0] or "anonymous") + " at " + hex(id(self)) + ">"
-
-    @classmethod
-    def like(cls, other, **kwargs):
-        """Create Signal based on another.
-
-        Parameters
-        ----------
-        other : _Value
-            Object to base this Signal on.
-
-        See `migen.fhdl.bitcontainer.value_bits_sign` for details.
-        """
-        from litex.gen.fhdl.bitcontainer import value_bits_sign
-        return cls(bits_sign=value_bits_sign(other), **kwargs)
-
-    def __hash__(self):
-        return self.duid
-
-
-class ClockSignal(_Value):
-    """Clock signal for a given clock domain
-
-    `ClockSignal` s for a given clock domain can be retrieved multiple
-    times. They all ultimately refer to the same signal.
-
-    Parameters
-    ----------
-    cd : str
-        Clock domain to obtain a clock signal for. Defaults to `"sys"`.
-    """
-    def __init__(self, cd="sys"):
-        _Value.__init__(self)
-        if not isinstance(cd, str):
-            raise TypeError("Argument of ClockSignal must be a string")
-        self.cd = cd
-
-
-class ResetSignal(_Value):
-    """Reset signal for a given clock domain
-
-    `ResetSignal` s for a given clock domain can be retrieved multiple
-    times. They all ultimately refer to the same signal.
-
-    Parameters
-    ----------
-    cd : str
-        Clock domain to obtain a reset signal for. Defaults to `"sys"`.
-    allow_reset_less : bool
-        If the clock domain is resetless, return 0 instead of reporting an
-        error.
-    """
-    def __init__(self, cd="sys", allow_reset_less=False):
-        _Value.__init__(self)
-        if not isinstance(cd, str):
-            raise TypeError("Argument of ResetSignal must be a string")
-        self.cd = cd
-        self.allow_reset_less = allow_reset_less
-
-
-# statements
-
-
-class _Statement:
-    pass
-
-
-class _Assign(_Statement):
-    def __init__(self, l, r):
-        self.l = wrap(l)
-        self.r = wrap(r)
-
-
-def _check_statement(s):
-    if isinstance(s, _collections.Iterable):
-        return all(_check_statement(ss) for ss in s)
-    else:
-        return isinstance(s, _Statement)
-
-
-class If(_Statement):
-    """Conditional execution of statements
-
-    Parameters
-    ----------
-    cond : _Value(1), in
-        Condition
-    *t : Statements
-        Statements to execute if `cond` is asserted.
-
-    Examples
-    --------
-    >>> a = Signal()
-    >>> b = Signal()
-    >>> c = Signal()
-    >>> d = Signal()
-    >>> If(a,
-    ...     b.eq(1)
-    ... ).Elif(c,
-    ...     b.eq(0)
-    ... ).Else(
-    ...     b.eq(d)
-    ... )
-    """
-    def __init__(self, cond, *t):
-        if not _check_statement(t):
-            raise TypeError("Not all test body objects are Migen statements")
-        self.cond = wrap(cond)
-        self.t = list(t)
-        self.f = []
-
-    def Else(self, *f):
-        """Add an `else` conditional block
-
-        Parameters
-        ----------
-        *f : Statements
-            Statements to execute if all previous conditions fail.
-        """
-        if not _check_statement(f):
-            raise TypeError("Not all test body objects are Migen statements")
-        _insert_else(self, list(f))
-        return self
-
-    def Elif(self, cond, *t):
-        """Add an `else if` conditional block
-
-        Parameters
-        ----------
-        cond : _Value(1), in
-            Condition
-        *t : Statements
-            Statements to execute if previous conditions fail and `cond`
-            is asserted.
-        """
-        _insert_else(self, [If(cond, *t)])
-        return self
-
-
-def _insert_else(obj, clause):
-    o = obj
-    while o.f:
-        assert(len(o.f) == 1)
-        assert(isinstance(o.f[0], If))
-        o = o.f[0]
-    o.f = clause
-
-
-class Case(_Statement):
-    """Case/Switch statement
-
-    Parameters
-    ----------
-    test : _Value, in
-        Selector value used to decide which block to execute
-    cases : dict
-        Dictionary of cases. The keys are numeric constants to compare
-        with `test`. The values are statements to be executed the
-        corresponding key matches `test`. The dictionary may contain a
-        string key `"default"` to mark a fall-through case that is
-        executed if no other key matches.
-
-    Examples
-    --------
-    >>> a = Signal()
-    >>> b = Signal()
-    >>> Case(a, {
-    ...     0:         b.eq(1),
-    ...     1:         b.eq(0),
-    ...     "default": b.eq(0),
-    ... })
-    """
-    def __init__(self, test, cases):
-        self.test = wrap(test)
-        self.cases = dict()
-        for k, v in cases.items():
-            if isinstance(k, (bool, int)):
-                k = Constant(k)
-            if (not isinstance(k, Constant) 
-                    and not (isinstance(k, str) and k == "default")):
-                raise TypeError("Case object is not a Migen constant")
-            if not isinstance(v, _collections.Iterable):
-                v = [v]
-            if not _check_statement(v):
-                raise TypeError("Not all objects for case {} "
-                                "are Migen statements".format(k))
-            self.cases[k] = v
-
-    def makedefault(self, key=None):
-        """Mark a key as the default case
-
-        Deletes/substitutes any previously existing default case.
-
-        Parameters
-        ----------
-        key : int or None
-            Key to use as default case if no other key matches.
-            By default, the largest key is the default key.
-        """
-        if key is None:
-            for choice in self.cases.keys():
-                if key is None or choice.value > key.value:
-                    key = choice
-        self.cases["default"] = self.cases[key]
-        del self.cases[key]
-        return self
-
-
-# arrays
-
-
-class _ArrayProxy(_Value):
-    def __init__(self, choices, key):
-        _Value.__init__(self)
-        self.choices = []
-        for c in choices:
-            if isinstance(c, (bool, int)):
-                c = Constant(c)
-            self.choices.append(c)
-        self.key = key
-
-    def __getattr__(self, attr):
-        return _ArrayProxy([getattr(choice, attr) for choice in self.choices],
-            self.key)
-
-    def __getitem__(self, key):
-        return _ArrayProxy([choice.__getitem__(key) for choice in self.choices],
-            self.key)
-
-
-class Array(list):
-    """Addressable multiplexer
-
-    An array is created from an iterable of values and indexed using the
-    usual Python simple indexing notation (no negative indices or
-    slices). It can be indexed by numeric constants, `_Value` s, or
-    `Signal` s.
-
-    The result of indexing the array is a proxy for the entry at the
-    given index that can be used on either RHS or LHS of assignments.
-
-    An array can be indexed multiple times.
-
-    Multidimensional arrays are supported by packing inner arrays into
-    outer arrays.
-
-    Parameters
-    ----------
-    values : iterable of ints, _Values, Signals
-        Entries of the array. Each entry can be a numeric constant, a
-        `Signal` or a `Record`.
-
-    Examples
-    --------
-    >>> a = Array(range(10))
-    >>> b = Signal(max=10)
-    >>> c = Signal(max=10)
-    >>> b.eq(a[9 - c])
-    """
-    def __getitem__(self, key):
-        if isinstance(key, Constant):
-            return list.__getitem__(self, key.value)
-        elif isinstance(key, _Value):
-            return _ArrayProxy(self, key)
-        else:
-            return list.__getitem__(self, key)
-
-
-class ClockDomain:
-    """Synchronous domain
-
-    Parameters
-    ----------
-    name : str or None
-        Domain name. If None (the default) the name is inferred from the
-        variable name this `ClockDomain` is assigned to (stripping any
-        `"cd_"` prefix).
-    reset_less : bool
-        The domain does not use a reset signal. Registers within this
-        domain are still all initialized to their reset state once, e.g.
-        through Verilog `"initial"` statements.
-
-    Attributes
-    ----------
-    clk : Signal, inout
-        The clock for this domain. Can be driven or used to drive other
-        signals (preferably in combinatorial context).
-    rst : Signal or None, inout
-        Reset signal for this domain. Can be driven or used to drive.
-    """
-    def __init__(self, name=None, reset_less=False):
-        self.name = _tracer.get_obj_var_name(name)
-        if self.name is None:
-            raise ValueError("Cannot extract clock domain name from code, need to specify.")
-        if self.name.startswith("cd_"):
-            self.name = self.name[3:]
-        if self.name[0].isdigit():
-            raise ValueError("Clock domain name cannot start with a number.")
-        self.clk = Signal(name_override=self.name + "_clk")
-        if reset_less:
-            self.rst = None
-        else:
-            self.rst = Signal(name_override=self.name + "_rst")
-
-    def rename(self, new_name):
-        """Rename the clock domain
-
-        Parameters
-        ----------
-        new_name : str
-            New name
-        """
-        self.name = new_name
-        self.clk.name_override = new_name + "_clk"
-        if self.rst is not None:
-            self.rst.name_override = new_name + "_rst"
-
-
-class _ClockDomainList(list):
-    def __getitem__(self, key):
-        if isinstance(key, str):
-            for cd in self:
-                if cd.name == key:
-                    return cd
-            raise KeyError(key)
-        else:
-            return list.__getitem__(self, key)
-
-
-(SPECIAL_INPUT, SPECIAL_OUTPUT, SPECIAL_INOUT) = range(3)
-
-
-class _Fragment:
-    def __init__(self, comb=None, sync=None, specials=None, clock_domains=None):
-        if comb is None: comb = []
-        if sync is None: sync = dict()
-        if specials is None: specials = set()
-        if clock_domains is None: clock_domains = _ClockDomainList()
-
-        self.comb = comb
-        self.sync = sync
-        self.specials = specials
-        self.clock_domains = _ClockDomainList(clock_domains)
-
-    def __add__(self, other):
-        newsync = _collections.defaultdict(list)
-        for k, v in self.sync.items():
-            newsync[k] = v[:]
-        for k, v in other.sync.items():
-            newsync[k].extend(v)
-        return _Fragment(self.comb + other.comb, newsync,
-            self.specials | other.specials,
-            self.clock_domains + other.clock_domains)
-
-    def __iadd__(self, other):
-        newsync = _collections.defaultdict(list)
-        for k, v in self.sync.items():
-            newsync[k] = v[:]
-        for k, v in other.sync.items():
-            newsync[k].extend(v)
-        self.comb += other.comb
-        self.sync = newsync
-        self.specials |= other.specials
-        self.clock_domains += other.clock_domains
-        return self
diff --git a/litex/gen/fhdl/tools.py b/litex/gen/fhdl/tools.py
deleted file mode 100644 (file)
index 3db9183..0000000
+++ /dev/null
@@ -1,298 +0,0 @@
-from litex.gen.fhdl.structure import *
-from litex.gen.fhdl.structure import _Slice, _Assign
-from litex.gen.fhdl.visit import NodeVisitor, NodeTransformer
-from litex.gen.fhdl.bitcontainer import value_bits_sign
-from litex.gen.util.misc import flat_iteration
-
-
-class _SignalLister(NodeVisitor):
-    def __init__(self):
-        self.output_list = set()
-
-    def visit_Signal(self, node):
-        self.output_list.add(node)
-
-
-class _TargetLister(NodeVisitor):
-    def __init__(self):
-        self.output_list = set()
-        self.target_context = False
-
-    def visit_Signal(self, node):
-        if self.target_context:
-            self.output_list.add(node)
-
-    def visit_Assign(self, node):
-        self.target_context = True
-        self.visit(node.l)
-        self.target_context = False
-
-    def visit_ArrayProxy(self, node):
-        for choice in node.choices:
-            self.visit(choice)
-
-
-class _InputLister(NodeVisitor):
-    def __init__(self):
-        self.output_list = set()
-
-    def visit_Signal(self, node):
-        self.output_list.add(node)
-
-    def visit_Assign(self, node):
-        self.visit(node.r)
-
-
-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 list_inputs(node):
-    lister = _InputLister()
-    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()
-    for order, stmt in enumerate(flat_iteration(sl)):
-        targets = set(list_targets(stmt))
-        group = [(order, stmt)]
-        disjoint = targets.isdisjoint(seen)
-        seen |= targets
-        if not disjoint:
-            groups, old_groups = [], groups
-            for old_targets, old_group in old_groups:
-                if targets.isdisjoint(old_targets):
-                    groups.append((old_targets, old_group))
-                else:
-                    targets |= old_targets
-                    group += old_group
-        groups.append((targets, group))
-    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()
-
-    def visit_ClockSignal(self, node):
-        self.clock_domains.add(node.cd)
-
-    def visit_ResetSignal(self, node):
-        self.clock_domains.add(node.cd)
-
-    def visit_clock_domains(self, node):
-        for clockname, statements in node.items():
-            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:
-        r |= special.list_clock_domains()
-    for cd in f.clock_domains:
-        r.add(cd.name)
-    return r
-
-
-def is_variable(node):
-    if isinstance(node, Signal):
-        return node.variable
-    elif isinstance(node, _Slice):
-        return is_variable(node.value)
-    elif isinstance(node, Cat):
-        arevars = list(map(is_variable, node.l))
-        r = arevars[0]
-        for x in arevars:
-            if x != r:
-                raise TypeError
-        return r
-    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.duid)]
-
-
-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():
-        if f.clock_domains[k].rst is not None:
-            newsync[k] = insert_reset(ResetSignal(k), v)
-        else:
-            newsync[k] = v
-    f.sync = newsync
-
-
-class _Lowerer(NodeTransformer):
-    def __init__(self):
-        self.target_context = False
-        self.extra_stmts = []
-        self.comb = []
-
-    def visit_Assign(self, node):
-        old_target_context, old_extra_stmts = self.target_context, self.extra_stmts
-        self.extra_stmts = []
-
-        self.target_context = True
-        lhs = self.visit(node.l)
-        self.target_context = False
-        rhs = self.visit(node.r)
-        r = _Assign(lhs, rhs)
-        if self.extra_stmts:
-            r = [r] + self.extra_stmts
-
-        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):
-    def __init__(self, clock_domains):
-        self.clock_domains = clock_domains
-        _Lowerer.__init__(self)
-
-    def visit_ArrayProxy(self, node):
-        # TODO: rewrite without variables
-        array_muxed = Signal(value_bits_sign(node), variable=True)
-        if self.target_context:
-            k = self.visit(node.key)
-            cases = {}
-            for n, choice in enumerate(node.choices):
-                cases[n] = [self.visit_Assign(_Assign(choice, array_muxed))]
-            self.extra_stmts.append(Case(k, cases).makedefault())
-        else:
-            cases = dict((n, _Assign(array_muxed, self.visit(choice)))
-                for n, choice in enumerate(node.choices))
-            self.comb.append(Case(self.visit(node.key), cases).makedefault())
-        return array_muxed
-
-    def visit_ClockSignal(self, node):
-        return self.clock_domains[node.cd].clk
-
-    def visit_ResetSignal(self, node):
-        rst = self.clock_domains[node.cd].rst
-        if rst is None:
-            if node.allow_reset_less:
-                return 0
-            else:
-                raise ValueError("Attempted to get reset signal of resetless"
-                                 " domain '{}'".format(node.cd))
-        else:
-            return rst
-
-
-class _ComplexSliceLowerer(_Lowerer):
-    def visit_Slice(self, node):
-        if not isinstance(node.value, Signal):
-            slice_proxy = Signal(value_bits_sign(node.value))
-            if self.target_context:
-                a = _Assign(node.value, slice_proxy)
-            else:
-                a = _Assign(slice_proxy, node.value)
-            self.comb.append(self.visit_Assign(a))
-            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
-
-    for special in f.specials:
-        for obj, attr, direction in special.iter_expressions():
-            if direction != SPECIAL_INOUT:
-                # inouts are only supported by Migen when connected directly to top-level
-                # in this case, they are Signal and never need lowering
-                l.comb = []
-                l.target_context = direction != SPECIAL_INPUT
-                l.extra_stmts = []
-                expr = getattr(obj, attr)
-                expr = l.visit(expr)
-                setattr(obj, attr, expr)
-                f.comb += l.comb + l.extra_stmts
-
-    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
-        self.new = new
-
-    def visit_ClockSignal(self, node):
-        if node.cd == self.old:
-            node.cd = self.new
-
-    def visit_ResetSignal(self, node):
-        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 new != old:
-        if old in f.sync:
-            if new in f.sync:
-                f.sync[new].extend(f.sync[old])
-            else:
-                f.sync[new] = f.sync[old]
-            del f.sync[old]
-    for special in f.specials:
-        special.rename_clock_domain(old, new)
-    try:
-        cd = f.clock_domains[old]
-    except KeyError:
-        pass
-    else:
-        cd.rename(new)
diff --git a/litex/gen/fhdl/tracer.py b/litex/gen/fhdl/tracer.py
deleted file mode 100644 (file)
index a394f93..0000000
+++ /dev/null
@@ -1,115 +0,0 @@
-import inspect
-from opcode import opname
-from collections import defaultdict
-
-
-def get_var_name(frame):
-    code = frame.f_code
-    call_index = frame.f_lasti
-    call_opc = opname[code.co_code[call_index]]
-    if call_opc != "CALL_FUNCTION" and call_opc != "CALL_FUNCTION_VAR":
-        return None
-    index = call_index+3
-    while True:
-        opc = opname[code.co_code[index]]
-        if opc == "STORE_NAME" or opc == "STORE_ATTR":
-            name_index = int(code.co_code[index+1])
-            return code.co_names[name_index]
-        elif opc == "STORE_FAST":
-            name_index = int(code.co_code[index+1])
-            return code.co_varnames[name_index]
-        elif opc == "STORE_DEREF":
-            name_index = int(code.co_code[index+1])
-            return code.co_cellvars[name_index]
-        elif opc == "LOAD_GLOBAL" or opc == "LOAD_ATTR" or opc == "LOAD_FAST" or opc == "LOAD_DEREF":
-            index += 3
-        elif opc == "DUP_TOP":
-            index += 1
-        elif opc == "BUILD_LIST":
-            index += 3
-        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
-
-    frame = inspect.currentframe().f_back
-    # We can be called via derived classes. Go back the stack frames
-    # until we reach the first class that does not inherit from us.
-    ourclass = frame.f_locals["self"].__class__
-    while "self" in frame.f_locals and isinstance(frame.f_locals["self"], ourclass):
-        frame = frame.f_back
-
-    vn = get_var_name(frame)
-    if vn is None:
-        vn = default
-    else:
-        vn = remove_underscore(vn)
-    return vn
-
-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
-    while frame is not None:
-        if varname is None:
-            varname = get_var_name(frame)
-        if varname is not None:
-            varname = remove_underscore(varname)
-            l.insert(0, (varname, name_to_idx[varname]))
-            name_to_idx[varname] += 1
-
-        try:
-            obj = frame.f_locals["self"]
-        except KeyError:
-            obj = None
-        if hasattr(obj, "__del__"):
-            obj = None
-
-        if obj is None:
-            if varname is not None:
-                coname = frame.f_code.co_name
-                if coname == "<module>":
-                    modules = frame.f_globals["__name__"]
-                    modules = modules.split(".")
-                    coname = modules[len(modules)-1]
-                coname = remove_underscore(coname)
-                l.insert(0, (coname, name_to_idx[coname]))
-                name_to_idx[coname] += 1
-        else:
-            classname = obj.__class__.__name__.lower()
-            try:
-                objs = classname_to_objs[classname]
-            except KeyError:
-                classname_to_objs[classname] = [obj]
-                idx = 0
-            else:
-                try:
-                    idx = index_id(objs, obj)
-                except ValueError:
-                    idx = len(objs)
-                    objs.append(obj)
-            classname = remove_underscore(classname)
-            l.insert(0, (classname, idx))
-
-        varname = None
-        frame = frame.f_back
-    return l
diff --git a/litex/gen/fhdl/verilog.py b/litex/gen/fhdl/verilog.py
deleted file mode 100644 (file)
index acca5f5..0000000
+++ /dev/null
@@ -1,361 +0,0 @@
-from functools import partial
-from operator import itemgetter
-import collections
-
-from litex.gen.fhdl.structure import *
-from litex.gen.fhdl.structure import _Operator, _Slice, _Assign, _Fragment
-from litex.gen.fhdl.tools import *
-from litex.gen.fhdl.bitcontainer import bits_for
-from litex.gen.fhdl.namer import build_namespace
-from litex.gen.fhdl.conv_output import ConvOutput
-
-
-_reserved_keywords = {
-    "always", "and", "assign", "automatic", "begin", "buf", "bufif0", "bufif1",
-    "case", "casex", "casez", "cell", "cmos", "config", "deassign", "default",
-    "defparam", "design", "disable", "edge", "else", "end", "endcase",
-    "endconfig", "endfunction", "endgenerate", "endmodule", "endprimitive",
-    "endspecify", "endtable", "endtask", "event", "for", "force", "forever",
-    "fork", "function", "generate", "genvar", "highz0", "highz1", "if",
-    "ifnone", "incdir", "include", "initial", "inout", "input",
-    "instance", "integer", "join", "large", "liblist", "library", "localparam",
-    "macromodule", "medium", "module", "nand", "negedge", "nmos", "nor",
-    "noshowcancelled", "not", "notif0", "notif1", "or", "output", "parameter",
-    "pmos", "posedge", "primitive", "pull0", "pull1" "pulldown",
-    "pullup", "pulsestyle_onevent", "pulsestyle_ondetect", "remos", "real",
-    "realtime", "reg", "release", "repeat", "rnmos", "rpmos", "rtran",
-    "rtranif0", "rtranif1", "scalared", "showcancelled", "signed", "small",
-    "specify", "specparam", "strong0", "strong1", "supply0", "supply1",
-    "table", "task", "time", "tran", "tranif0", "tranif1", "tri", "tri0",
-    "tri1", "triand", "trior", "trireg", "unsigned", "use", "vectored", "wait",
-    "wand", "weak0", "weak1", "while", "wire", "wor","xnor", "xor"
-}
-
-
-def _printsig(ns, s):
-    if s.signed:
-        n = "signed "
-    else:
-        n = ""
-    if len(s) > 1:
-        n += "[" + str(len(s)-1) + ":0] "
-    n += ns.get_name(s)
-    return n
-
-
-def _printconstant(node):
-    if node.signed:
-        return (str(node.nbits) + "'sd" + str(2**node.nbits + node.value),
-                True)
-    else:
-        return str(node.nbits) + "'d" + str(node.value), False
-
-
-def _printexpr(ns, node):
-    if isinstance(node, Constant):
-        return _printconstant(node)
-    elif isinstance(node, Signal):
-        return ns.get_name(node), node.signed
-    elif isinstance(node, _Operator):
-        arity = len(node.operands)
-        r1, s1 = _printexpr(ns, node.operands[0])
-        if arity == 1:
-            if node.op == "-":
-                if s1:
-                    r = node.op + r1
-                else:
-                    r = "-$signed({1'd0, " + r1 + "})"
-                s = True
-            else:
-                r = node.op + r1
-                s = s1
-        elif arity == 2:
-            r2, s2 = _printexpr(ns, node.operands[1])
-            if node.op not in ["<<<", ">>>"]:
-                if s2 and not s1:
-                    r1 = "$signed({1'd0, " + r1 + "})"
-                if s1 and not s2:
-                    r2 = "$signed({1'd0, " + r2 + "})"
-            r = r1 + " " + node.op + " " + r2
-            s = s1 or s2
-        elif arity == 3:
-            assert node.op == "m"
-            r2, s2 = _printexpr(ns, node.operands[1])
-            r3, s3 = _printexpr(ns, node.operands[2])
-            if s2 and not s3:
-                r3 = "$signed({1'd0, " + r3 + "})"
-            if s3 and not s2:
-                r2 = "$signed({1'd0, " + r2 + "})"
-            r = r1 + " ? " + r2 + " : " + r3
-            s = s2 or s3
-        else:
-            raise TypeError
-        return "(" + r + ")", s
-    elif isinstance(node, _Slice):
-        # Verilog does not like us slicing non-array signals...
-        if isinstance(node.value, Signal) \
-          and len(node.value) == 1 \
-          and node.start == 0 and node.stop == 1:
-              return _printexpr(ns, node.value)
-
-        if node.start + 1 == node.stop:
-            sr = "[" + str(node.start) + "]"
-        else:
-            sr = "[" + str(node.stop-1) + ":" + str(node.start) + "]"
-        r, s = _printexpr(ns, node.value)
-        return r + sr, s
-    elif isinstance(node, Cat):
-        l = [_printexpr(ns, v)[0] for v in reversed(node.l)]
-        return "{" + ", ".join(l) + "}", False
-    elif isinstance(node, Replicate):
-        return "{" + str(node.n) + "{" + _printexpr(ns, node.v)[0] + "}}", False
-    else:
-        raise TypeError("Expression of unrecognized type: '{}'".format(type(node).__name__))
-
-
-(_AT_BLOCKING, _AT_NONBLOCKING, _AT_SIGNAL) = range(3)
-
-
-def _printnode(ns, at, level, node):
-    if node is None:
-        return ""
-    elif isinstance(node, _Assign):
-        if at == _AT_BLOCKING:
-            assignment = " = "
-        elif at == _AT_NONBLOCKING:
-            assignment = " <= "
-        elif is_variable(node.l):
-            assignment = " = "
-        else:
-            assignment = " <= "
-        return "\t"*level + _printexpr(ns, node.l)[0] + assignment + _printexpr(ns, node.r)[0] + ";\n"
-    elif isinstance(node, collections.Iterable):
-        return "".join(list(map(partial(_printnode, ns, at, level), node)))
-    elif isinstance(node, If):
-        r = "\t"*level + "if (" + _printexpr(ns, node.cond)[0] + ") begin\n"
-        r += _printnode(ns, at, level + 1, node.t)
-        if node.f:
-            r += "\t"*level + "end else begin\n"
-            r += _printnode(ns, at, level + 1, node.f)
-        r += "\t"*level + "end\n"
-        return r
-    elif isinstance(node, Case):
-        if node.cases:
-            r = "\t"*level + "case (" + _printexpr(ns, node.test)[0] + ")\n"
-            css = [(k, v) for k, v in node.cases.items() if isinstance(k, Constant)]
-            css = sorted(css, key=lambda x: x[0].value)
-            for choice, statements in css:
-                r += "\t"*(level + 1) + _printexpr(ns, choice)[0] + ": begin\n"
-                r += _printnode(ns, at, level + 2, statements)
-                r += "\t"*(level + 1) + "end\n"
-            if "default" in node.cases:
-                r += "\t"*(level + 1) + "default: begin\n"
-                r += _printnode(ns, at, level + 2, node.cases["default"])
-                r += "\t"*(level + 1) + "end\n"
-            r += "\t"*level + "endcase\n"
-            return r
-        else:
-            return ""
-    else:
-        raise TypeError("Node of unrecognized type: "+str(type(node)))
-
-
-def _list_comb_wires(f):
-    r = set()
-    groups = group_by_targets(f.comb)
-    for g in groups:
-        if len(g[1]) == 1 and isinstance(g[1][0], _Assign):
-            r |= g[0]
-    return r
-
-
-def _printheader(f, ios, name, ns,
-                 reg_initialization):
-    sigs = list_signals(f) | list_special_ios(f, True, True, True)
-    special_outs = list_special_ios(f, False, True, True)
-    inouts = list_special_ios(f, False, False, True)
-    targets = list_targets(f) | special_outs
-    wires = _list_comb_wires(f) | special_outs
-    r = "module " + name + "(\n"
-    firstp = True
-    for sig in sorted(ios, key=lambda x: x.duid):
-        if not firstp:
-            r += ",\n"
-        firstp = False
-        if sig in inouts:
-            r += "\tinout " + _printsig(ns, sig)
-        elif sig in targets:
-            if sig in wires:
-                r += "\toutput " + _printsig(ns, sig)
-            else:
-                r += "\toutput reg " + _printsig(ns, sig)
-        else:
-            r += "\tinput " + _printsig(ns, sig)
-    r += "\n);\n\n"
-    for sig in sorted(sigs - ios, key=lambda x: x.duid):
-        if sig in wires:
-            r += "wire " + _printsig(ns, sig) + ";\n"
-        else:
-            if reg_initialization:
-                r += "reg " + _printsig(ns, sig) + " = " + _printexpr(ns, sig.reset)[0] + ";\n"
-            else:
-                r += "reg " + _printsig(ns, sig) + ";\n"
-    r += "\n"
-    return r
-
-
-def _printcomb(f, ns,
-               display_run,
-               dummy_signal,
-               blocking_assign):
-    r = ""
-    if f.comb:
-        if dummy_signal:
-            # Generate a dummy event to get the simulator
-            # to run the combinatorial process once at the beginning.
-            syn_off = "// synthesis translate_off\n"
-            syn_on = "// synthesis translate_on\n"
-            dummy_s = Signal(name_override="dummy_s")
-            r += syn_off
-            r += "reg " + _printsig(ns, dummy_s) + ";\n"
-            r += "initial " + ns.get_name(dummy_s) + " <= 1'd0;\n"
-            r += syn_on
-
-        groups = group_by_targets(f.comb)
-
-        for n, g in enumerate(groups):
-            if len(g[1]) == 1 and isinstance(g[1][0], _Assign):
-                r += "assign " + _printnode(ns, _AT_BLOCKING, 0, g[1][0])
-            else:
-                if dummy_signal:
-                    dummy_d = Signal(name_override="dummy_d")
-                    r += "\n" + syn_off
-                    r += "reg " + _printsig(ns, dummy_d) + ";\n"
-                    r += syn_on
-
-                r += "always @(*) begin\n"
-                if display_run:
-                    r += "\t$display(\"Running comb block #" + str(n) + "\");\n"
-                if blocking_assign:
-                    for t in g[0]:
-                        r += "\t" + ns.get_name(t) + " = " + _printexpr(ns, t.reset)[0] + ";\n"
-                    r += _printnode(ns, _AT_BLOCKING, 1, g[1])
-                else:
-                    for t in g[0]:
-                        r += "\t" + ns.get_name(t) + " <= " + _printexpr(ns, t.reset)[0] + ";\n"
-                    r += _printnode(ns, _AT_NONBLOCKING, 1, g[1])
-                if dummy_signal:
-                    r += syn_off
-                    r += "\t" + ns.get_name(dummy_d) + " <= " + ns.get_name(dummy_s) + ";\n"
-                    r += syn_on
-                r += "end\n"
-    r += "\n"
-    return r
-
-
-def _printsync(f, ns):
-    r = ""
-    for k, v in sorted(f.sync.items(), key=itemgetter(0)):
-        r += "always @(posedge " + ns.get_name(f.clock_domains[k].clk) + ") begin\n"
-        r += _printnode(ns, _AT_SIGNAL, 1, v)
-        r += "end\n\n"
-    return r
-
-
-def _call_special_classmethod(overrides, obj, method, *args, **kwargs):
-    cl = obj.__class__
-    if cl in overrides:
-        cl = overrides[cl]
-    if hasattr(cl, method):
-        return getattr(cl, method)(obj, *args, **kwargs)
-    else:
-        return None
-
-
-def _lower_specials_step(overrides, specials):
-    f = _Fragment()
-    lowered_specials = set()
-    for special in sorted(specials, key=lambda x: x.duid):
-        impl = _call_special_classmethod(overrides, special, "lower")
-        if impl is not None:
-            f += impl.get_fragment()
-            lowered_specials.add(special)
-    return f, lowered_specials
-
-
-def _can_lower(overrides, specials):
-    for special in specials:
-        cl = special.__class__
-        if cl in overrides:
-            cl = overrides[cl]
-        if hasattr(cl, "lower"):
-            return True
-    return False
-
-
-def _lower_specials(overrides, specials):
-    f, lowered_specials = _lower_specials_step(overrides, specials)
-    while _can_lower(overrides, f.specials):
-        f2, lowered_specials2 = _lower_specials_step(overrides, f.specials)
-        f += f2
-        lowered_specials |= lowered_specials2
-        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.duid):
-        pr = _call_special_classmethod(overrides, special, "emit_verilog", ns, add_data_file)
-        if pr is None:
-            raise NotImplementedError("Special " + str(special) + " failed to implement emit_verilog")
-        r += pr
-    return r
-
-
-def convert(f, ios=None, name="top",
-  special_overrides=dict(),
-  create_clock_domains=True,
-  display_run=False, asic_syntax=False):
-    r = ConvOutput()
-    if not isinstance(f, _Fragment):
-        f = f.get_fragment()
-    if ios is None:
-        ios = set()
-
-    for cd_name in sorted(list_clock_domains(f)):
-        try:
-            f.clock_domains[cd_name]
-        except KeyError:
-            if create_clock_domains:
-                cd = ClockDomain(cd_name)
-                f.clock_domains.append(cd)
-                ios |= {cd.clk, cd.rst}
-            else:
-                raise KeyError("Unresolved clock domain: '"+cd_name+"'")
-
-    f = lower_complex_slices(f)
-    insert_resets(f)
-    f = lower_basics(f)
-    fs, lowered_specials = _lower_specials(special_overrides, f.specials)
-    f += lower_basics(fs)
-
-    ns = build_namespace(list_signals(f) \
-        | list_special_ios(f, True, True, True) \
-        | ios, _reserved_keywords)
-    ns.clock_domains = f.clock_domains
-    r.ns = ns
-
-    src = "/* Machine-generated using LiteX */\n"
-    src += _printheader(f, ios, name, ns,
-                        reg_initialization=not asic_syntax)
-    src += _printcomb(f, ns,
-                      display_run=display_run,
-                      dummy_signal=not asic_syntax,
-                      blocking_assign=asic_syntax)
-    src += _printsync(f, ns)
-    src += _printspecials(special_overrides, f.specials - lowered_specials, ns, r.add_data_file)
-    src += "endmodule\n"
-    r.set_main_source(src)
-
-    return r
diff --git a/litex/gen/fhdl/visit.py b/litex/gen/fhdl/visit.py
deleted file mode 100644 (file)
index 0ccd509..0000000
+++ /dev/null
@@ -1,202 +0,0 @@
-from copy import copy
-
-from litex.gen.fhdl.structure import *
-from litex.gen.fhdl.structure import (_Operator, _Slice, _Assign, _ArrayProxy,
-                                  _Fragment)
-
-
-class NodeVisitor:
-    def visit(self, node):
-        if isinstance(node, Constant):
-            self.visit_Constant(node)
-        elif isinstance(node, Signal):
-            self.visit_Signal(node)
-        elif isinstance(node, ClockSignal):
-            self.visit_ClockSignal(node)
-        elif isinstance(node, ResetSignal):
-            self.visit_ResetSignal(node)
-        elif isinstance(node, _Operator):
-            self.visit_Operator(node)
-        elif isinstance(node, _Slice):
-            self.visit_Slice(node)
-        elif isinstance(node, Cat):
-            self.visit_Cat(node)
-        elif isinstance(node, Replicate):
-            self.visit_Replicate(node)
-        elif isinstance(node, _Assign):
-            self.visit_Assign(node)
-        elif isinstance(node, If):
-            self.visit_If(node)
-        elif isinstance(node, Case):
-            self.visit_Case(node)
-        elif isinstance(node, _Fragment):
-            self.visit_Fragment(node)
-        elif isinstance(node, (list, tuple)):
-            self.visit_statements(node)
-        elif isinstance(node, dict):
-            self.visit_clock_domains(node)
-        elif isinstance(node, _ArrayProxy):
-            self.visit_ArrayProxy(node)
-        elif node is not None:
-            self.visit_unknown(node)
-
-    def visit_Constant(self, node):
-        pass
-
-    def visit_Signal(self, node):
-        pass
-
-    def visit_ClockSignal(self, node):
-        pass
-
-    def visit_ResetSignal(self, node):
-        pass
-
-    def visit_Operator(self, node):
-        for o in node.operands:
-            self.visit(o)
-
-    def visit_Slice(self, node):
-        self.visit(node.value)
-
-    def visit_Cat(self, node):
-        for e in node.l:
-            self.visit(e)
-
-    def visit_Replicate(self, node):
-        self.visit(node.v)
-
-    def visit_Assign(self, node):
-        self.visit(node.l)
-        self.visit(node.r)
-
-    def visit_If(self, node):
-        self.visit(node.cond)
-        self.visit(node.t)
-        self.visit(node.f)
-
-    def visit_Case(self, node):
-        self.visit(node.test)
-        for v, statements in node.cases.items():
-            self.visit(statements)
-
-    def visit_Fragment(self, node):
-        self.visit(node.comb)
-        self.visit(node.sync)
-
-    def visit_statements(self, node):
-        for statement in node:
-            self.visit(statement)
-
-    def visit_clock_domains(self, node):
-        for clockname, statements in node.items():
-            self.visit(statements)
-
-    def visit_ArrayProxy(self, node):
-        for choice in node.choices:
-            self.visit(choice)
-        self.visit(node.key)
-
-    def visit_unknown(self, node):
-        pass
-
-
-# Default methods always copy the node, except for:
-# - Signals, ClockSignals and ResetSignals
-# - Unknown objects
-# - All fragment fields except comb and sync
-# In those cases, the original node is returned unchanged.
-class NodeTransformer:
-    def visit(self, node):
-        if isinstance(node, Constant):
-            return self.visit_Constant(node)
-        elif isinstance(node, Signal):
-            return self.visit_Signal(node)
-        elif isinstance(node, ClockSignal):
-            return self.visit_ClockSignal(node)
-        elif isinstance(node, ResetSignal):
-            return self.visit_ResetSignal(node)
-        elif isinstance(node, _Operator):
-            return self.visit_Operator(node)
-        elif isinstance(node, _Slice):
-            return self.visit_Slice(node)
-        elif isinstance(node, Cat):
-            return self.visit_Cat(node)
-        elif isinstance(node, Replicate):
-            return self.visit_Replicate(node)
-        elif isinstance(node, _Assign):
-            return self.visit_Assign(node)
-        elif isinstance(node, If):
-            return self.visit_If(node)
-        elif isinstance(node, Case):
-            return self.visit_Case(node)
-        elif isinstance(node, _Fragment):
-            return self.visit_Fragment(node)
-        elif isinstance(node, (list, tuple)):
-            return self.visit_statements(node)
-        elif isinstance(node, dict):
-            return self.visit_clock_domains(node)
-        elif isinstance(node, _ArrayProxy):
-            return self.visit_ArrayProxy(node)
-        elif node is not None:
-            return self.visit_unknown(node)
-        else:
-            return None
-
-    def visit_Constant(self, node):
-        return node
-
-    def visit_Signal(self, node):
-        return node
-
-    def visit_ClockSignal(self, node):
-        return node
-
-    def visit_ResetSignal(self, node):
-        return node
-
-    def visit_Operator(self, node):
-        return _Operator(node.op, [self.visit(o) for o in node.operands])
-
-    def visit_Slice(self, node):
-        return _Slice(self.visit(node.value), node.start, node.stop)
-
-    def visit_Cat(self, node):
-        return Cat(*[self.visit(e) for e in node.l])
-
-    def visit_Replicate(self, node):
-        return Replicate(self.visit(node.v), node.n)
-
-    def visit_Assign(self, node):
-        return _Assign(self.visit(node.l), self.visit(node.r))
-
-    def visit_If(self, node):
-        r = If(self.visit(node.cond))
-        r.t = self.visit(node.t)
-        r.f = self.visit(node.f)
-        return r
-
-    def visit_Case(self, node):
-        cases = dict((v, self.visit(statements)) for v, statements in node.cases.items())
-        r = Case(self.visit(node.test), cases)
-        return r
-
-    def visit_Fragment(self, node):
-        r = copy(node)
-        r.comb = self.visit(node.comb)
-        r.sync = self.visit(node.sync)
-        return r
-
-    # NOTE: this will always return a list, even if node is a tuple
-    def visit_statements(self, node):
-        return [self.visit(statement) for statement in node]
-
-    def visit_clock_domains(self, node):
-        return dict((clockname, self.visit(statements)) for clockname, statements in node.items())
-
-    def visit_ArrayProxy(self, node):
-        return _ArrayProxy([self.visit(choice) for choice in node.choices],
-            self.visit(node.key))
-
-    def visit_unknown(self, node):
-        return node
diff --git a/litex/gen/genlib/__init__.py b/litex/gen/genlib/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/litex/gen/genlib/cdc.py b/litex/gen/genlib/cdc.py
deleted file mode 100644 (file)
index 90b5f90..0000000
+++ /dev/null
@@ -1,141 +0,0 @@
-from litex.gen.fhdl.structure import *
-from litex.gen.fhdl.module import Module
-from litex.gen.fhdl.specials import Special
-from litex.gen.fhdl.bitcontainer import value_bits_sign
-from litex.gen.genlib.misc import WaitTimer
-
-
-class NoRetiming(Special):
-    def __init__(self, reg):
-        Special.__init__(self)
-        self.reg = reg
-
-    # do nothing
-    @staticmethod
-    def lower(dr):
-        return Module()
-
-
-class MultiRegImpl(Module):
-    def __init__(self, i, o, odomain, n):
-        self.i = i
-        self.o = o
-        self.odomain = odomain
-
-        w, signed = value_bits_sign(self.i)
-        self.regs = [Signal((w, signed)) for i in range(n)]
-
-        ###
-
-        src = self.i
-        for reg in self.regs:
-            sd = getattr(self.sync, self.odomain)
-            sd += reg.eq(src)
-            src = reg
-        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)
-        self.i = wrap(i)
-        self.o = wrap(o)
-        self.odomain = odomain
-        self.n = n
-
-    def iter_expressions(self):
-        yield self, "i", SPECIAL_INPUT
-        yield self, "o", SPECIAL_OUTPUT
-
-    def rename_clock_domain(self, old, new):
-        Special.rename_clock_domain(self, old, new)
-        if self.odomain == old:
-            self.odomain = new
-
-    def list_clock_domains(self):
-        r = Special.list_clock_domains(self)
-        r.add(self.odomain)
-        return r
-
-    @staticmethod
-    def lower(dr):
-        return MultiRegImpl(dr.i, dr.o, dr.odomain, dr.n)
-
-
-class PulseSynchronizer(Module):
-    def __init__(self, idomain, odomain):
-        self.i = Signal()
-        self.o = Signal()
-
-        ###
-
-        toggle_i = Signal()
-        toggle_o = Signal()
-        toggle_o_r = Signal()
-
-        sync_i = getattr(self.sync, idomain)
-        sync_o = getattr(self.sync, odomain)
-
-        sync_i += If(self.i, toggle_i.eq(~toggle_i))
-        self.specials += MultiReg(toggle_i, toggle_o, odomain)
-        sync_o += toggle_o_r.eq(toggle_o)
-        self.comb += self.o.eq(toggle_o ^ toggle_o_r)
-
-
-class BusSynchronizer(Module):
-    """Clock domain transfer of several bits at once.
-
-    Ensures that all the bits form a single word that was present
-    synchronously in the input clock domain (unlike direct use of
-    ``MultiReg``)."""
-    def __init__(self, width, idomain, odomain, timeout=128):
-        self.i = Signal(width)
-        self.o = Signal(width)
-
-        if width == 1:
-            self.specials += MultiReg(self.i, self.o, odomain)
-        else:
-            sync_i = getattr(self.sync, idomain)
-            sync_o = getattr(self.sync, odomain)
-
-            starter = Signal(reset=1)
-            sync_i += starter.eq(0)
-            self.submodules._ping = PulseSynchronizer(idomain, odomain)
-            self.submodules._pong = PulseSynchronizer(odomain, idomain)
-            self.submodules._timeout = WaitTimer(timeout)
-            self.comb += [
-                self._timeout.wait.eq(~self._ping.i),
-                self._ping.i.eq(starter | self._pong.o | self._timeout.done),
-                self._pong.i.eq(self._ping.i)
-            ]
-
-            ibuffer = Signal(width)
-            obuffer = Signal(width)
-            sync_i += If(self._pong.o, ibuffer.eq(self.i))
-            self.specials += MultiReg(ibuffer, obuffer, odomain)
-            sync_o += If(self._ping.o, self.o.eq(obuffer))
-
-
-class GrayCounter(Module):
-    def __init__(self, width):
-        self.ce = Signal()
-        self.q = Signal(width)
-        self.q_next = Signal(width)
-        self.q_binary = Signal(width)
-        self.q_next_binary = Signal(width)
-
-        ###
-
-        self.comb += [
-            If(self.ce,
-                self.q_next_binary.eq(self.q_binary + 1)
-            ).Else(
-                self.q_next_binary.eq(self.q_binary)
-            ),
-            self.q_next.eq(self.q_next_binary ^ self.q_next_binary[1:])
-        ]
-        self.sync += [
-            self.q_binary.eq(self.q_next_binary),
-            self.q.eq(self.q_next)
-        ]
diff --git a/litex/gen/genlib/coding.py b/litex/gen/genlib/coding.py
deleted file mode 100644 (file)
index 80d62d6..0000000
+++ /dev/null
@@ -1,98 +0,0 @@
-"""
-Encoders and decoders between binary and one-hot representation
-"""
-
-from litex.gen.fhdl.structure import *
-from litex.gen.fhdl.module import Module
-
-
-class Encoder(Module):
-    """Encode one-hot to binary
-
-    If `n` is low, the `o` th bit in `i` is asserted, else none or
-    multiple bits are asserted.
-
-    Parameters
-    ----------
-    width : int
-        Bit width of the input
-
-    Attributes
-    ----------
-    i : Signal(width), in
-        One-hot input
-    o : Signal(max=width), out
-        Encoded binary
-    n : Signal(1), out
-        Invalid, either none or multiple input bits are asserted
-    """
-    def __init__(self, width):
-        self.i = Signal(width)  # one-hot
-        self.o = Signal(max=max(2, width))  # binary
-        self.n = Signal()  # invalid: none or multiple
-        act = dict((1<<j, self.o.eq(j)) for j in range(width))
-        act["default"] = self.n.eq(1)
-        self.comb += Case(self.i, act)
-
-
-class PriorityEncoder(Module):
-    """Priority encode requests to binary
-
-    If `n` is low, the `o` th bit in `i` is asserted and the bits below
-    `o` are unasserted, else `o == 0`. The LSB has priority.
-
-    Parameters
-    ----------
-    width : int
-        Bit width of the input
-
-    Attributes
-    ----------
-    i : Signal(width), in
-        Input requests
-    o : Signal(max=width), out
-        Encoded binary
-    n : Signal(1), out
-        Invalid, no input bits are asserted
-    """
-    def __init__(self, width):
-        self.i = Signal(width)  # one-hot, lsb has priority
-        self.o = Signal(max=max(2, width))  # binary
-        self.n = Signal()  # none
-        for j in range(width)[::-1]:  # last has priority
-            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
-
-    If `n` is low, the `i` th bit in `o` is asserted, the others are
-    not, else `o == 0`.
-
-    Parameters
-    ----------
-    width : int
-        Bit width of the output
-
-    Attributes
-    ----------
-    i : Signal(max=width), in
-        Input binary
-    o : Signal(width), out
-        Decoded one-hot
-    n : Signal(1), in
-        Invalid, no output bits are to be asserted
-    """
-
-    def __init__(self, width):
-        self.i = Signal(max=max(2, width))  # binary
-        self.n = Signal()  # none/invalid
-        self.o = Signal(width)  # one-hot
-        act = dict((j, self.o.eq(1<<j)) for j in range(width))
-        self.comb += Case(self.i, act)
-        self.comb += If(self.n, self.o.eq(0))
-
-
-class PriorityDecoder(Decoder):
-    pass  # same
diff --git a/litex/gen/genlib/divider.py b/litex/gen/genlib/divider.py
deleted file mode 100644 (file)
index 841e7ad..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-from litex.gen.fhdl.structure import *
-from litex.gen.fhdl.module import Module
-
-
-class Divider(Module):
-    def __init__(self, w):
-        self.start_i = Signal()
-        self.dividend_i = Signal(w)
-        self.divisor_i = Signal(w)
-        self.ready_o = Signal()
-        self.quotient_o = Signal(w)
-        self.remainder_o = Signal(w)
-
-        ###
-
-        qr = Signal(2*w)
-        counter = Signal(max=w+1)
-        divisor_r = Signal(w)
-        diff = Signal(w+1)
-
-        self.comb += [
-            self.quotient_o.eq(qr[:w]),
-            self.remainder_o.eq(qr[w:]),
-            self.ready_o.eq(counter == 0),
-            diff.eq(qr[w-1:] - divisor_r)
-        ]
-        self.sync += [
-            If(self.start_i,
-                counter.eq(w),
-                qr.eq(self.dividend_i),
-                divisor_r.eq(self.divisor_i)
-            ).Elif(~self.ready_o,
-                    If(diff[w],
-                        qr.eq(Cat(0, qr[:2*w-1]))
-                    ).Else(
-                        qr.eq(Cat(1, qr[:w-1], diff[:w]))
-                    ),
-                    counter.eq(counter - 1)
-            )
-        ]
diff --git a/litex/gen/genlib/fifo.py b/litex/gen/genlib/fifo.py
deleted file mode 100644 (file)
index 167f964..0000000
+++ /dev/null
@@ -1,214 +0,0 @@
-from litex.gen.fhdl.structure import *
-from litex.gen.fhdl.module import Module
-from litex.gen.fhdl.specials import Memory
-from litex.gen.fhdl.bitcontainer import log2_int
-from litex.gen.fhdl.decorators import ClockDomainsRenamer
-from litex.gen.genlib.cdc import NoRetiming, MultiReg, GrayCounter
-
-
-def _inc(signal, modulo):
-    if modulo == 2**len(signal):
-        return signal.eq(signal + 1)
-    else:
-        return If(signal == (modulo - 1),
-            signal.eq(0)
-        ).Else(
-            signal.eq(signal + 1)
-        )
-
-
-class _FIFOInterface:
-    """
-    Data written to the input interface (`din`, `we`, `writable`) is
-    buffered and can be read at the output interface (`dout`, `re`,
-    `readable`). The data entry written first to the input
-    also appears first on the output.
-
-    Parameters
-    ----------
-    width : int
-        Bit width for the data.
-    depth : int
-        Depth of the FIFO.
-
-    Attributes
-    ----------
-    din : in, width
-        Input data
-    writable : out
-        There is space in the FIFO and `we` can be asserted to load new data.
-    we : in
-        Write enable signal to latch `din` into the FIFO. Does nothing if
-        `writable` is not asserted.
-    dout : out, width
-        Output data. Only valid if `readable` is asserted.
-    readable : out
-        Output data `dout` valid, FIFO not empty.
-    re : in
-        Acknowledge `dout`. If asserted, the next entry will be
-        available on the next cycle (if `readable` is high then).
-    """
-    def __init__(self, width, depth):
-        self.we = Signal()
-        self.writable = Signal()  # not full
-        self.re = Signal()
-        self.readable = Signal()  # not empty
-
-        self.din = Signal(width)
-        self.dout = Signal(width)
-        self.width = width
-
-
-class SyncFIFO(Module, _FIFOInterface):
-    """Synchronous FIFO (first in, first out)
-
-    Read and write interfaces are accessed from the same clock domain.
-    If different clock domains are needed, use :class:`AsyncFIFO`.
-
-    {interface}
-    level : out
-        Number of unread entries.
-    replace : in
-        Replaces the last entry written into the FIFO with `din`. Does nothing
-        if that entry has already been read (i.e. the FIFO is empty).
-        Assert in conjunction with `we`.
-    """
-    __doc__ = __doc__.format(interface=_FIFOInterface.__doc__)
-
-    def __init__(self, width, depth, fwft=True):
-        _FIFOInterface.__init__(self, width, depth)
-
-        self.level = Signal(max=depth+1)
-        self.replace = Signal()
-
-        ###
-
-        produce = Signal(max=depth)
-        consume = Signal(max=depth)
-        storage = Memory(self.width, depth)
-        self.specials += storage
-
-        wrport = storage.get_port(write_capable=True)
-        self.specials += wrport
-        self.comb += [
-            If(self.replace,
-                wrport.adr.eq(produce-1)
-            ).Else(
-                wrport.adr.eq(produce)
-            ),
-            wrport.dat_w.eq(self.din),
-            wrport.we.eq(self.we & (self.writable | self.replace))
-        ]
-        self.sync += If(self.we & self.writable & ~self.replace,
-            _inc(produce, depth))
-
-        do_read = Signal()
-        self.comb += do_read.eq(self.readable & self.re)
-
-        rdport = storage.get_port(async_read=fwft, has_re=not fwft)
-        self.specials += rdport
-        self.comb += [
-            rdport.adr.eq(consume),
-            self.dout.eq(rdport.dat_r)
-        ]
-        if not fwft:
-            self.comb += rdport.re.eq(do_read)
-        self.sync += If(do_read, _inc(consume, depth))
-
-        self.sync += \
-            If(self.we & self.writable & ~self.replace,
-                If(~do_read, self.level.eq(self.level + 1))
-            ).Elif(do_read,
-                self.level.eq(self.level - 1)
-            )
-        self.comb += [
-            self.writable.eq(self.level != depth),
-            self.readable.eq(self.level != 0)
-        ]
-
-
-class SyncFIFOBuffered(Module, _FIFOInterface):
-    def __init__(self, width, depth):
-        _FIFOInterface.__init__(self, width, depth)
-        self.submodules.fifo = fifo = SyncFIFO(width, depth, False)
-
-        self.writable = fifo.writable
-        self.din = fifo.din
-        self.we = fifo.we
-        self.dout = fifo.dout
-        self.level = Signal(max=depth+2)
-
-        ###
-
-        self.comb += fifo.re.eq(fifo.readable & (~self.readable | self.re))
-        self.sync += \
-            If(fifo.re,
-                self.readable.eq(1),
-            ).Elif(self.re,
-                self.readable.eq(0),
-            )
-        self.comb += self.level.eq(fifo.level + self.readable)
-
-
-class AsyncFIFO(Module, _FIFOInterface):
-    """Asynchronous FIFO (first in, first out)
-
-    Read and write interfaces are accessed from different clock domains,
-    named `read` and `write`. Use `ClockDomainsRenamer` to rename to
-    other names.
-
-    {interface}
-    """
-    __doc__ = __doc__.format(interface=_FIFOInterface.__doc__)
-
-    def __init__(self, width, depth):
-        _FIFOInterface.__init__(self, width, depth)
-
-        ###
-
-        depth_bits = log2_int(depth, True)
-
-        produce = ClockDomainsRenamer("write")(GrayCounter(depth_bits+1))
-        consume = ClockDomainsRenamer("read")(GrayCounter(depth_bits+1))
-        self.submodules += produce, consume
-        self.comb += [
-            produce.ce.eq(self.writable & self.we),
-            consume.ce.eq(self.readable & self.re)
-        ]
-
-        produce_rdomain = Signal(depth_bits+1)
-        self.specials += [
-            NoRetiming(produce.q),
-            MultiReg(produce.q, produce_rdomain, "read")
-        ]
-        consume_wdomain = Signal(depth_bits+1)
-        self.specials += [
-            NoRetiming(consume.q),
-            MultiReg(consume.q, consume_wdomain, "write")
-        ]
-        if depth_bits == 1:
-            self.comb += self.writable.eq((produce.q[-1] == consume_wdomain[-1])
-                | (produce.q[-2] == consume_wdomain[-2]))
-        else:
-            self.comb += [
-                self.writable.eq((produce.q[-1] == consume_wdomain[-1])
-                | (produce.q[-2] == consume_wdomain[-2])
-                | (produce.q[:-2] != consume_wdomain[:-2]))
-            ]
-        self.comb += self.readable.eq(consume.q != produce_rdomain)
-
-        storage = Memory(self.width, depth)
-        self.specials += storage
-        wrport = storage.get_port(write_capable=True, clock_domain="write")
-        self.specials += wrport
-        self.comb += [
-            wrport.adr.eq(produce.q_binary[:-1]),
-            wrport.dat_w.eq(self.din),
-            wrport.we.eq(produce.ce)
-        ]
-        rdport = storage.get_port(clock_domain="read")
-        self.specials += rdport
-        self.comb += [
-            rdport.adr.eq(consume.q_next_binary[:-1]),
-            self.dout.eq(rdport.dat_r)
-        ]
diff --git a/litex/gen/genlib/fsm.py b/litex/gen/genlib/fsm.py
deleted file mode 100644 (file)
index de20e74..0000000
+++ /dev/null
@@ -1,176 +0,0 @@
-from collections import OrderedDict
-
-from litex.gen.fhdl.structure import *
-from litex.gen.fhdl.structure import _Statement, _Slice, _ArrayProxy
-from litex.gen.fhdl.module import Module, FinalizeError
-from litex.gen.fhdl.visit import NodeTransformer
-from litex.gen.fhdl.bitcontainer import value_bits_sign
-
-
-__all__ = ["AnonymousState", "NextState", "NextValue", "FSM"]
-
-
-class AnonymousState:
-    pass
-
-
-# do not use namedtuple here as it inherits tuple
-# and the latter is used elsewhere in FHDL
-class NextState(_Statement):
-    def __init__(self, state):
-        self.state = state
-
-
-class NextValue(_Statement):
-    def __init__(self, target, value):
-        self.target = target
-        self.value = value
-
-
-def _target_eq(a, b):
-    if type(a) != type(b):
-        return False
-    ty = type(a)
-    if ty == Constant:
-        return a.value == b.value
-    elif ty == Signal:
-        return a is b
-    elif ty == Cat:
-        return all(_target_eq(x, y) for x, y in zip(a.l, b.l))
-    elif ty == _Slice:
-        return (_target_eq(a.value, b.value)
-                    and a.start == b.start
-                    and a.end == b.end)
-    elif ty == _ArrayProxy:
-        return (all(_target_eq(x, y) for x, y in zip(a.choices, b.choices))
-                    and _target_eq(a.key, b.key))
-    else:
-        raise ValueError("NextValue cannot be used with target type '{}'"
-                         .format(ty))
-
-
-class _LowerNext(NodeTransformer):
-    def __init__(self, next_state_signal, encoding, aliases):
-        self.next_state_signal = next_state_signal
-        self.encoding = encoding
-        self.aliases = aliases
-        # (target, next_value_ce, next_value)
-        self.registers = []
-
-    def _get_register_control(self, target):
-        for x in self.registers:
-            if _target_eq(target, x[0]):
-                return x[1], x[2]
-        raise KeyError
-
-    def visit_unknown(self, node):
-        if isinstance(node, NextState):
-            try:
-                actual_state = self.aliases[node.state]
-            except KeyError:
-                actual_state = node.state
-            return self.next_state_signal.eq(self.encoding[actual_state])
-        elif isinstance(node, NextValue):
-            try:
-                next_value_ce, next_value = self._get_register_control(node.target)
-            except KeyError:
-                related = node.target if isinstance(node.target, Signal) else None
-                next_value = Signal(bits_sign=value_bits_sign(node.target), related=related)
-                next_value_ce = Signal(related=related)
-                self.registers.append((node.target, next_value_ce, next_value))
-            return next_value.eq(node.value), next_value_ce.eq(1)
-        else:
-            return node
-
-
-class FSM(Module):
-    def __init__(self, reset_state=None):
-        self.actions = OrderedDict()
-        self.state_aliases = dict()
-        self.reset_state = reset_state
-
-        self.before_entering_signals = OrderedDict()
-        self.before_leaving_signals = OrderedDict()
-        self.after_entering_signals = OrderedDict()
-        self.after_leaving_signals = OrderedDict()
-
-    def act(self, state, *statements):
-        if self.finalized:
-            raise FinalizeError
-        if self.reset_state is None:
-            self.reset_state = state
-        if state not in self.actions:
-            self.actions[state] = []
-        self.actions[state] += statements
-
-    def delayed_enter(self, name, target, delay):
-        if self.finalized:
-            raise FinalizeError
-        if delay > 0:
-            state = name
-            for i in range(delay):
-                if i == delay - 1:
-                    next_state = target
-                else:
-                    next_state = AnonymousState()
-                self.act(state, NextState(next_state))
-                state = next_state
-        else:
-            self.state_aliases[name] = target
-
-    def ongoing(self, state):
-        is_ongoing = Signal()
-        self.act(state, is_ongoing.eq(1))
-        return is_ongoing
-
-    def _get_signal(self, d, state):
-        if state not in self.actions:
-            self.actions[state] = []
-        try:
-            return d[state]
-        except KeyError:
-            is_el = Signal()
-            d[state] = is_el
-            return is_el
-
-    def before_entering(self, state):
-        return self._get_signal(self.before_entering_signals, state)
-
-    def before_leaving(self, state):
-        return self._get_signal(self.before_leaving_signals, state)
-
-    def after_entering(self, state):
-        signal = self._get_signal(self.after_entering_signals, state)
-        self.sync += signal.eq(self.before_entering(state))
-        return signal
-
-    def after_leaving(self, state):
-        signal = self._get_signal(self.after_leaving_signals, state)
-        self.sync += signal.eq(self.before_leaving(state))
-        return signal
-
-    def do_finalize(self):
-        nstates = len(self.actions)
-        self.encoding = dict((s, n) for n, s in enumerate(self.actions.keys()))
-        self.state = Signal(max=nstates, reset=self.encoding[self.reset_state])
-        self.next_state = Signal(max=nstates)
-
-        ln = _LowerNext(self.next_state, self.encoding, self.state_aliases)
-        cases = dict((self.encoding[k], ln.visit(v)) for k, v in self.actions.items() if v)
-        self.comb += [
-            self.next_state.eq(self.state),
-            Case(self.state, cases).makedefault(self.encoding[self.reset_state])
-        ]
-        self.sync += self.state.eq(self.next_state)
-        for register, next_value_ce, next_value in ln.registers:
-            self.sync += If(next_value_ce, register.eq(next_value))
-
-        # drive entering/leaving signals
-        for state, signal in self.before_leaving_signals.items():
-            encoded = self.encoding[state]
-            self.comb += signal.eq((self.state == encoded) & ~(self.next_state == encoded))
-        if self.reset_state in self.after_entering_signals:
-            self.after_entering_signals[self.reset_state].reset = 1
-        for state, signal in self.before_entering_signals.items():
-            encoded = self.encoding[state]
-            self.comb += signal.eq(~(self.state == encoded) & (self.next_state == encoded))
diff --git a/litex/gen/genlib/io.py b/litex/gen/genlib/io.py
deleted file mode 100644 (file)
index 5c441e6..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-from litex.gen.fhdl.structure import *
-from litex.gen.fhdl.module import Module
-from litex.gen.fhdl.specials import Special
-
-
-class DifferentialInput(Special):
-    def __init__(self, i_p, i_n, o):
-        Special.__init__(self)
-        self.i_p = wrap(i_p)
-        self.i_n = wrap(i_n)
-        self.o = wrap(o)
-
-    def iter_expressions(self):
-        yield self, "i_p", SPECIAL_INPUT
-        yield self, "i_n", SPECIAL_INPUT
-        yield self, "o", SPECIAL_OUTPUT
-
-    @staticmethod
-    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)
-        self.i = wrap(i)
-        self.o_p = wrap(o_p)
-        self.o_n = wrap(o_n)
-
-    def iter_expressions(self):
-        yield self, "i", SPECIAL_INPUT
-        yield self, "o_p", SPECIAL_OUTPUT
-        yield self, "o_n", SPECIAL_OUTPUT
-
-    @staticmethod
-    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()
-        self.clock_domains.cd_por = ClockDomain(reset_less=True)
-
-        if hasattr(clk, "p"):
-            clk_se = Signal()
-            self.specials += DifferentialInput(clk.p, clk.n, clk_se)
-            clk = clk_se
-
-        # Power on Reset (vendor agnostic)
-        int_rst = Signal(reset=1)
-        self.sync.por += int_rst.eq(rst)
-        self.comb += [
-            self.cd_sys.clk.eq(clk),
-            self.cd_por.clk.eq(clk),
-            self.cd_sys.rst.eq(int_rst)
-        ]
-
-
-class DDRInput(Special):
-    def __init__(self, i, o1, o2, clk=ClockSignal()):
-        Special.__init__(self)
-        self.i = wrap(i)
-        self.o1 = wrap(o1)
-        self.o2 = wrap(o2)
-        self.clk = wrap(clk)
-
-    def iter_expressions(self):
-        yield self, "i", SPECIAL_INPUT
-        yield self, "o1", SPECIAL_OUTPUT
-        yield self, "o2", SPECIAL_OUTPUT
-        yield self, "clk", SPECIAL_INPUT
-
-    @staticmethod
-    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)
-        self.i1 = i1
-        self.i2 = i2
-        self.o = o
-        self.clk = clk
-
-    def iter_expressions(self):
-        yield self, "i1", SPECIAL_INPUT
-        yield self, "i2", SPECIAL_INPUT
-        yield self, "o", SPECIAL_OUTPUT
-        yield self, "clk", SPECIAL_INPUT
-
-    @staticmethod
-    def lower(dr):
-        raise NotImplementedError("Attempted to use a DDR output, but platform does not support them")
-
diff --git a/litex/gen/genlib/misc.py b/litex/gen/genlib/misc.py
deleted file mode 100644 (file)
index 42ad878..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-from litex.gen.fhdl.structure import *
-from litex.gen.fhdl.module import Module
-from litex.gen.fhdl.bitcontainer import bits_for
-
-
-def split(v, *counts):
-    r = []
-    offset = 0
-    for n in counts:
-        if n != 0:
-            r.append(v[offset:offset+n])
-        else:
-            r.append(None)
-        offset += n
-    return tuple(r)
-
-
-def displacer(signal, shift, output, n=None, reverse=False):
-    if shift is None:
-        return output.eq(signal)
-    if n is None:
-        n = 2**len(shift)
-    w = len(signal)
-    if reverse:
-        r = reversed(range(n))
-    else:
-        r = range(n)
-    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)
-    if n is None:
-        n = 2**len(shift)
-    w = len(output)
-    cases = {}
-    for i in range(n):
-        if reverse:
-            s = n - i - 1
-        else:
-            s = i
-        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)
-
-    counterlogic = If(counter != 0,
-        counter.eq(counter + 1)
-    ).Elif(trigger,
-        counter.eq(1)
-    )
-    # insert counter reset if it doesn't naturally overflow
-    # (test if lastevent+1 is a power of 2)
-    if (lastevent & (lastevent + 1)) != 0:
-        counterlogic = If(counter == lastevent,
-            counter.eq(0)
-        ).Else(
-            counterlogic
-        )
-
-    def get_cond(e):
-        if e[0] == 0:
-            return trigger & (counter == 0)
-        else:
-            return counter == e[0]
-    sync = [If(get_cond(e), *e[1]) for e in events]
-    sync.append(counterlogic)
-    return sync
-
-
-class WaitTimer(Module):
-    def __init__(self, t):
-        self.wait = Signal()
-        self.done = Signal()
-
-        # # #
-
-        count = Signal(bits_for(t), reset=t)
-        self.comb += self.done.eq(count == 0)
-        self.sync += \
-            If(self.wait,
-                If(~self.done, count.eq(count - 1))
-            ).Else(count.eq(count.reset))
diff --git a/litex/gen/genlib/record.py b/litex/gen/genlib/record.py
deleted file mode 100644 (file)
index 0038b06..0000000
+++ /dev/null
@@ -1,179 +0,0 @@
-from litex.gen.fhdl.structure import *
-from litex.gen.fhdl.tracer import get_obj_var_name
-
-from functools import reduce
-from operator import or_
-
-
-(DIR_NONE, DIR_S_TO_M, DIR_M_TO_S) = range(3)
-
-# Possible layout elements:
-#   1. (name, size)
-#   2. (name, size, direction)
-#   3. (name, sublayout)
-# 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):
-            try:
-                return layout_dict[p]
-            except KeyError:
-                return p
-        else:
-            return p
-
-    r = []
-    for f in layout:
-        if isinstance(f[1], (int, tuple, str)):  # cases 1/2
-            if len(f) == 3:
-                r.append((f[0], resolve(f[1]), f[2]))
-            else:
-                r.append((f[0], resolve(f[1])))
-        elif isinstance(f[1], list):  # case 3
-            r.append((f[0], set_layout_parameters(f[1], **layout_dict)))
-        else:
-            raise TypeError
-    return r
-
-
-def layout_len(layout):
-    r = 0
-    for f in layout:
-        if isinstance(f[1], (int, tuple)):  # cases 1/2
-            if len(f) == 3:
-                fname, fsize, fdirection = f
-            else:
-                fname, fsize = f
-        elif isinstance(f[1], list):  # case 3
-            fname, fsublayout = f
-            fsize = layout_len(fsublayout)
-        else:
-            raise TypeError
-        if isinstance(fsize, tuple):
-            r += fsize[0]
-        else:
-            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:
-        path_s = path.split("/")
-        last = path_s.pop()
-        copy_ref = layout
-        insert_ref = r
-        for hop in path_s:
-            name, copy_ref = layout_get(copy_ref, hop)
-            try:
-                name, insert_ref = layout_get(insert_ref, hop)
-            except KeyError:
-                new_insert_ref = []
-                insert_ref.append((hop, new_insert_ref))
-                insert_ref = new_insert_ref
-        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, "")
-        self.layout = layout
-
-        if self.name:
-            prefix = self.name + "_"
-        else:
-            prefix = ""
-        for f in self.layout:
-            if isinstance(f[1], (int, tuple)):  # cases 1/2
-                if(len(f) == 3):
-                    fname, fsize, fdirection = f
-                else:
-                    fname, fsize = f
-                finst = Signal(fsize, name=prefix + fname)
-            elif isinstance(f[1], list):  # case 3
-                fname, fsublayout = f
-                finst = Record(fsublayout, prefix + fname)
-            else:
-                raise TypeError
-            setattr(self, fname, finst)
-
-    def eq(self, other):
-        return [getattr(self, f[0]).eq(getattr(other, f[0]))
-          for f in self.layout if hasattr(other, f[0])]
-
-    def iter_flat(self):
-        for f in self.layout:
-            e = getattr(self, f[0])
-            if isinstance(e, Signal):
-                if len(f) == 3:
-                    yield e, f[2]
-                else:
-                    yield e, DIR_NONE
-            elif isinstance(e, Record):
-                yield from e.iter_flat()
-            else:
-                raise TypeError
-
-    def flatten(self):
-        return [signal for signal, direction in self.iter_flat()]
-
-    def raw_bits(self):
-        return Cat(*self.flatten())
-
-    def connect(self, *slaves, leave_out=set()):
-        if isinstance(leave_out, str):
-            leave_out = {leave_out}
-        r = []
-        for f in self.layout:
-            field = f[0]
-            if field not in leave_out:
-                self_e = getattr(self, field)
-                if isinstance(self_e, Signal):
-                    direction = f[2]
-                    if direction == DIR_M_TO_S:
-                        r += [getattr(slave, field).eq(self_e) for slave in slaves]
-                    elif direction == DIR_S_TO_M:
-                        r.append(self_e.eq(reduce(or_, [getattr(slave, field) for slave in slaves])))
-                    else:
-                        raise TypeError
-                else:
-                    for slave in slaves:
-                        r += self_e.connect(getattr(slave, field), leave_out=leave_out)
-        return r
-
-    def connect_flat(self, *slaves):
-        r = []
-        iter_slaves = [slave.iter_flat() for slave in slaves]
-        for m_signal, m_direction in self.iter_flat():
-            if m_direction == DIR_M_TO_S:
-                for iter_slave in iter_slaves:
-                    s_signal, s_direction = next(iter_slave)
-                    assert(s_direction == DIR_M_TO_S)
-                    r.append(s_signal.eq(m_signal))
-            elif m_direction == DIR_S_TO_M:
-                s_signals = []
-                for iter_slave in iter_slaves:
-                    s_signal, s_direction = next(iter_slave)
-                    assert(s_direction == DIR_S_TO_M)
-                    s_signals.append(s_signal)
-                r.append(m_signal.eq(reduce(or_, s_signals)))
-            else:
-                raise TypeError
-        return r
-
-    def __len__(self):
-        return layout_len(self.layout)
-
-    def __repr__(self):
-        return "<Record " + ":".join(f[0] for f in self.layout) + " at " + hex(id(self)) + ">"
diff --git a/litex/gen/genlib/resetsync.py b/litex/gen/genlib/resetsync.py
deleted file mode 100644 (file)
index 061f65b..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-from litex.gen.fhdl.structure import *
-from litex.gen.fhdl.specials import Special
-
-
-class AsyncResetSynchronizer(Special):
-    def __init__(self, cd, async_reset):
-        Special.__init__(self)
-        self.cd = cd
-        self.async_reset = wrap(async_reset)
-
-    def iter_expressions(self):
-        yield self.cd, "clk", SPECIAL_INPUT
-        yield self.cd, "rst", SPECIAL_OUTPUT
-        yield self, "async_reset", SPECIAL_INPUT
-
-    @staticmethod
-    def lower(dr):
-        raise NotImplementedError("Attempted to use a reset synchronizer, but platform does not support them")
diff --git a/litex/gen/genlib/roundrobin.py b/litex/gen/genlib/roundrobin.py
deleted file mode 100644 (file)
index b9903db..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-from litex.gen.fhdl.structure import *
-from litex.gen.fhdl.module import Module
-
-
-(SP_WITHDRAW, SP_CE) = range(2)
-
-
-class RoundRobin(Module):
-    def __init__(self, n, switch_policy=SP_WITHDRAW):
-        self.request = Signal(n)
-        self.grant = Signal(max=max(2, n))
-        self.switch_policy = switch_policy
-        if self.switch_policy == SP_CE:
-            self.ce = Signal()
-
-        ###
-
-        if n > 1:
-            cases = {}
-            for i in range(n):
-                switch = []
-                for j in reversed(range(i+1, i+n)):
-                    t = j % n
-                    switch = [
-                        If(self.request[t],
-                            self.grant.eq(t)
-                        ).Else(
-                            *switch
-                        )
-                    ]
-                if self.switch_policy == SP_WITHDRAW:
-                    case = [If(~self.request[i], *switch)]
-                else:
-                    case = switch
-                cases[i] = case
-            statement = Case(self.grant, cases)
-            if self.switch_policy == SP_CE:
-                statement = If(self.ce, statement)
-            self.sync += statement
-        else:
-            self.comb += self.grant.eq(0)
diff --git a/litex/gen/genlib/sort.py b/litex/gen/genlib/sort.py
deleted file mode 100644 (file)
index ff5b617..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-from litex.gen.fhdl.structure import *
-from litex.gen.fhdl.module import Module
-
-
-class BitonicSort(Module):
-    """Combinatorial sorting network
-
-    The Bitonic sort is implemented as a combinatorial sort using
-    comparators and multiplexers. Its asymptotic complexity (in terms of
-    number of comparators/muxes) is O(n log(n)**2), like mergesort or
-    shellsort.
-
-    http://www.dps.uibk.ac.at/~cosenza/teaching/gpu/sort-batcher.pdf
-
-    http://www.inf.fh-flensburg.de/lang/algorithmen/sortieren/bitonic/bitonicen.htm
-
-    http://www.myhdl.org/doku.php/cookbook:bitonic
-
-    Parameters
-    ----------
-    n : int
-        Number of inputs and output signals.
-    m : int
-        Bit width of inputs and outputs. Or a tuple of `(m, signed)`.
-    ascending : bool
-        Sort direction. `True` if input is to be sorted ascending,
-        `False` for descending. Defaults to ascending.
-
-    Attributes
-    ----------
-    i : list of Signals, in
-        Input values, each `m` wide.
-    o : list of Signals, out
-        Output values, sorted, each `m` bits wide.
-    """
-    def __init__(self, n, m, ascending=True):
-        self.i = [Signal(m) for i in range(n)]
-        self.o = [Signal(m) for i in range(n)]
-        self._sort(self.i, self.o, int(ascending), m)
-
-    def _sort_two(self, i0, i1, o0, o1, dir):
-        self.comb += [
-                o0.eq(i0),
-                o1.eq(i1),
-                If(dir == (i0 > i1),
-                    o0.eq(i1),
-                    o1.eq(i0),
-                )]
-
-    def _merge(self, i, o, dir, m):
-        n = len(i)
-        k = n//2
-        if n > 1:
-            t = [Signal(m) for j in range(n)]
-            for j in range(k):
-                self._sort_two(i[j], i[j + k], t[j], t[j + k], dir)
-            self._merge(t[:k], o[:k], dir, m)
-            self._merge(t[k:], o[k:], dir, m)
-        else:
-            self.comb += o[0].eq(i[0])
-
-    def _sort(self, i, o, dir, m):
-        n = len(i)
-        k = n//2
-        if n > 1:
-            t = [Signal(m) for j in range(n)]
-            self._sort(i[:k], t[:k], 1, m)  # ascending
-            self._sort(i[k:], t[k:], 0, m)  # descending
-            self._merge(t, o, dir, m)
-        else:
-            self.comb += o[0].eq(i[0])
diff --git a/litex/gen/sim/__init__.py b/litex/gen/sim/__init__.py
deleted file mode 100644 (file)
index 327f1c8..0000000
+++ /dev/null
@@ -1 +0,0 @@
-from litex.gen.sim.core import Simulator, run_simulation
diff --git a/litex/gen/sim/core.py b/litex/gen/sim/core.py
deleted file mode 100644 (file)
index dbafc71..0000000
+++ /dev/null
@@ -1,335 +0,0 @@
-import operator
-import collections
-import inspect
-
-from litex.gen.fhdl.structure import *
-from litex.gen.fhdl.structure import (_Value, _Statement,
-                                  _Operator, _Slice, _ArrayProxy,
-                                  _Assign, _Fragment)
-from litex.gen.fhdl.bitcontainer import value_bits_sign
-from litex.gen.fhdl.tools import list_signals, list_targets, insert_resets
-from litex.gen.fhdl.simplify import MemoryToArray
-from litex.gen.fhdl.specials import _MemoryLocation
-from litex.gen.sim.vcd import VCDWriter, DummyVCDWriter
-
-
-class ClockState:
-    def __init__(self, high, half_period, time_before_trans):
-        self.high = high
-        self.half_period = half_period
-        self.time_before_trans = time_before_trans
-
-
-class TimeManager:
-    def __init__(self, description):
-        self.clocks = dict()
-
-        for k, period_phase in description.items():
-            if isinstance(period_phase, tuple):
-                period, phase = period_phase
-            else:
-                period = period_phase
-                phase = 0
-            half_period = period//2
-            if phase >= half_period:
-                phase -= half_period
-                high = True
-            else:
-                high = False
-            self.clocks[k] = ClockState(high, half_period, half_period - phase)
-    
-    def tick(self):
-        rising = set()
-        falling = set()
-        dt = min(cs.time_before_trans for cs in self.clocks.values())
-        for k, cs in self.clocks.items():
-            if cs.time_before_trans == dt:
-                cs.high = not cs.high
-                if cs.high:
-                    rising.add(k)
-                else:
-                    falling.add(k)
-            cs.time_before_trans -= dt
-            if not cs.time_before_trans:
-                cs.time_before_trans += cs.half_period
-        return dt, rising, falling
-
-
-str2op = {
-    "~": operator.invert,
-    "+": operator.add,
-    "-": operator.sub,
-    "*": operator.mul,
-    
-    ">>>": operator.rshift,
-    "<<<": operator.lshift,
-    
-    "&": operator.and_,
-    "^": operator.xor,
-    "|": operator.or_,
-    
-    "<": operator.lt,
-    "<=": operator.le,
-    "==": operator.eq,
-    "!=": operator.ne,
-    ">": operator.gt,
-    ">=": operator.ge,
-}
-
-
-def _truncate(value, nbits, signed):
-    value = value & (2**nbits - 1)
-    if signed and (value & 2**(nbits - 1)):
-        value -= 2**nbits
-    return value
-
-
-class Evaluator:
-    def __init__(self, clock_domains, replaced_memories):
-        self.clock_domains = clock_domains
-        self.replaced_memories = replaced_memories
-        self.signal_values = dict()
-        self.modifications = dict()
-
-    def commit(self):
-        r = set()
-        for k, v in self.modifications.items():
-            if k not in self.signal_values or self.signal_values[k] != v:
-                self.signal_values[k] = v
-                r.add(k)
-        self.modifications.clear()
-        return r
-
-    def eval(self, node, postcommit=False):
-        if isinstance(node, Constant):
-            return node.value
-        elif isinstance(node, Signal):
-            if postcommit:
-                try:
-                    return self.modifications[node]
-                except KeyError:
-                    pass
-            try:
-                return self.signal_values[node]
-            except KeyError:
-                return node.reset.value
-        elif isinstance(node, _Operator):
-            operands = [self.eval(o, postcommit) for o in node.operands]
-            if node.op == "-":
-                if len(operands) == 1:
-                    return -operands[0]
-                else:
-                    return operands[0] - operands[1]
-            elif node.op == "m":
-                return operands[1] if operands[0] else operands[2]
-            else:
-                return str2op[node.op](*operands)
-        elif isinstance(node, _Slice):
-            v = self.eval(node.value, postcommit)
-            idx = range(node.start, node.stop)
-            return sum(((v >> i) & 1) << j for j, i in enumerate(idx))
-        elif isinstance(node, Cat):
-            shift = 0
-            r = 0
-            for element in node.l:
-                nbits = len(element)
-                # make value always positive
-                r |= (self.eval(element, postcommit) & (2**nbits-1)) << shift
-                shift += nbits
-            return r
-        elif isinstance(node, _ArrayProxy):
-            return self.eval(node.choices[self.eval(node.key, postcommit)],
-                             postcommit)
-        elif isinstance(node, _MemoryLocation):
-            array = self.replaced_memories[node.memory]
-            return self.eval(array[self.eval(node.index, postcommit)], postcommit)
-        elif isinstance(node, ClockSignal):
-            return self.eval(self.clock_domains[node.cd].clk, postcommit)
-        elif isinstance(node, ResetSignal):
-            rst = self.clock_domains[node.cd].rst
-            if rst is None:
-                if node.allow_reset_less:
-                    return 0
-                else:
-                    raise ValueError("Attempted to get reset signal of resetless"
-                                     " domain '{}'".format(node.cd))
-            else:
-                return self.eval(rst, postcommit)
-        else:
-            raise NotImplementedError
-
-    def assign(self, node, value):
-        if isinstance(node, Signal):
-            assert not node.variable
-            self.modifications[node] = _truncate(value,
-                                                 node.nbits, node.signed)
-        elif isinstance(node, Cat):
-            for element in node.l:
-                nbits = len(element)
-                self.assign(element, value & (2**nbits-1))
-                value >>= nbits
-        elif isinstance(node, _Slice):
-            full_value = self.eval(node.value, True)
-            # clear bits assigned to by the slice
-            full_value &= ~((2**node.stop-1) - (2**node.start-1))
-            # set them to the new value
-            value &= 2**(node.stop - node.start)-1
-            full_value |= value << node.start
-            self.assign(node.value, full_value)
-        elif isinstance(node, _ArrayProxy):
-            self.assign(node.choices[self.eval(node.key)], value)
-        elif isinstance(node, _MemoryLocation):
-            array = self.replaced_memories[node.memory]
-            self.assign(array[self.eval(node.index)], value)
-        else:
-            raise NotImplementedError
-
-    def execute(self, statements):
-        for s in statements:
-            if isinstance(s, _Assign):
-                self.assign(s.l, self.eval(s.r))
-            elif isinstance(s, If):
-                if self.eval(s.cond) & (2**len(s.cond) - 1):
-                    self.execute(s.t)
-                else:
-                    self.execute(s.f)
-            elif isinstance(s, Case):
-                nbits, signed = value_bits_sign(s.test)
-                test = _truncate(self.eval(s.test), nbits, signed)
-                found = False
-                for k, v in s.cases.items():
-                    if isinstance(k, Constant) and k.value == test:
-                        self.execute(v)
-                        found = True
-                        break
-                if not found and "default" in s.cases:
-                    self.execute(s.cases["default"])
-            elif isinstance(s, collections.Iterable):
-                self.execute(s)
-            else:
-                raise NotImplementedError
-
-
-# TODO: instances via Iverilog/VPI
-class Simulator:
-    def __init__(self, fragment_or_module, generators, clocks={"sys": 10}, vcd_name=None):
-        if isinstance(fragment_or_module, _Fragment):
-            self.fragment = fragment_or_module
-        else:
-            self.fragment = fragment_or_module.get_fragment()
-        if not isinstance(generators, dict):
-            generators = {"sys": generators}
-        self.generators = dict()
-        for k, v in generators.items():
-            if (isinstance(v, collections.Iterable)
-                    and not inspect.isgenerator(v)):
-                self.generators[k] = list(v)
-            else:
-                self.generators[k] = [v]
-
-        self.time = TimeManager(clocks)
-        for clock in clocks.keys():
-            if clock not in self.fragment.clock_domains:
-                cd = ClockDomain(name=clock, reset_less=True)
-                cd.clk.reset = C(self.time.clocks[clock].high)
-                self.fragment.clock_domains.append(cd)
-
-        mta = MemoryToArray()
-        mta.transform_fragment(None, self.fragment)
-        insert_resets(self.fragment)
-        # comb signals return to their reset value if nothing assigns them
-        self.fragment.comb[0:0] = [s.eq(s.reset)
-                                   for s in list_targets(self.fragment.comb)]
-        self.evaluator = Evaluator(self.fragment.clock_domains,
-                                   mta.replacements)
-
-        if vcd_name is None:
-            self.vcd = DummyVCDWriter()
-        else:
-            signals = list_signals(self.fragment)
-            for cd in self.fragment.clock_domains:
-                signals.add(cd.clk)
-                if cd.rst is not None:
-                    signals.add(cd.rst)
-            for memory_array in mta.replacements.values():
-                signals |= set(memory_array)
-            signals = sorted(signals, key=lambda x: x.duid)
-            self.vcd = VCDWriter(vcd_name, signals)
-
-    def __enter__(self):
-        return self
-
-    def __exit__(self, type, value, traceback):
-        self.close()
-
-    def close(self):
-        self.vcd.close()
-
-    def _commit_and_comb_propagate(self):
-        # TODO: optimize
-        all_modified = set()
-        modified = self.evaluator.commit()
-        all_modified |= modified
-        while modified:
-            self.evaluator.execute(self.fragment.comb)
-            modified = self.evaluator.commit()
-            all_modified |= modified
-        for signal in all_modified:
-            self.vcd.set(signal, self.evaluator.signal_values[signal])
-
-    def _evalexec_nested_lists(self, x):
-        if isinstance(x, list):
-            return [self._evalexec_nested_lists(e) for e in x]
-        elif isinstance(x, _Value):
-            return self.evaluator.eval(x)
-        elif isinstance(x, _Statement):
-            self.evaluator.execute([x])
-            return None
-        else:
-            raise ValueError
-
-    def _process_generators(self, cd):
-        exhausted = []
-        for generator in self.generators[cd]:
-            reply = None
-            while True:
-                try:
-                    request = generator.send(reply)
-                    if request is None:
-                        break  # next cycle
-                    else:
-                        reply = self._evalexec_nested_lists(request)
-                except StopIteration:
-                    exhausted.append(generator)
-                    break
-        for generator in exhausted:
-            self.generators[cd].remove(generator)
-
-    def _continue_simulation(self):
-        # TODO: passive generators
-        return any(self.generators.values())
-
-    def run(self):
-        self.evaluator.execute(self.fragment.comb)
-        self._commit_and_comb_propagate()
-
-        while True:
-            dt, rising, falling = self.time.tick()
-            self.vcd.delay(dt)
-            for cd in rising:
-                self.evaluator.assign(self.fragment.clock_domains[cd].clk, 1)
-                if cd in self.fragment.sync:
-                    self.evaluator.execute(self.fragment.sync[cd])
-                if cd in self.generators:
-                    self._process_generators(cd)
-            for cd in falling:
-                self.evaluator.assign(self.fragment.clock_domains[cd].clk, 0)
-            self._commit_and_comb_propagate()
-
-            if not self._continue_simulation():
-                break
-
-
-def run_simulation(*args, **kwargs):
-    with Simulator(*args, **kwargs) as s:
-        s.run()
diff --git a/litex/gen/sim/vcd.py b/litex/gen/sim/vcd.py
deleted file mode 100644 (file)
index 335486b..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-from itertools import count
-
-from litex.gen.fhdl.namer import build_namespace
-
-
-def vcd_codes():
-    codechars = [chr(i) for i in range(33, 127)]
-    for n in count():
-        q, r = divmod(n, len(codechars))
-        code = codechars[r]
-        while q > 0:
-            q, r = divmod(q, len(codechars))
-            code = codechars[r] + code
-        yield code
-
-
-class VCDWriter:
-    def __init__(self, filename, signals):
-        self.fo = open(filename, "w")
-        self.codes = dict()
-        self.signal_values = dict()
-        self.t = 0
-
-        try:
-            ns = build_namespace(signals)
-            codes = vcd_codes()
-            for signal in signals:
-                name = ns.get_name(signal)
-                code = next(codes)
-                self.codes[signal] = code
-                self.fo.write("$var wire {len} {code} {name} $end\n"
-                              .format(name=name, code=code, len=len(signal)))
-            self.fo.write("$dumpvars\n")
-            for signal in signals:
-                value = signal.reset.value
-                self._write_value(signal, value)
-                self.signal_values[signal] = value
-            self.fo.write("$end\n")
-            self.fo.write("#0\n")
-        except:
-            self.close()
-            raise
-
-    def _write_value(self, signal, value):
-        l = len(signal)
-        if value < 0:
-            value += 2**l
-        if l > 1:
-            fmtstr = "b{:0" + str(l) + "b} {}\n"
-        else:
-            fmtstr = "{}{}\n"
-        self.fo.write(fmtstr.format(value, self.codes[signal]))
-
-    def set(self, signal, value):
-        if self.signal_values[signal] != value:
-            self._write_value(signal, value)
-            self.signal_values[signal] = value
-
-    def delay(self, delay):
-        self.t += delay
-        self.fo.write("#{}\n".format(self.t))
-
-    def close(self):
-        self.fo.close()
-
-
-class DummyVCDWriter:
-    def set(self, signal, value):
-        pass
-
-    def delay(self, delay):
-        pass
-
-    def close(self):
-        pass
diff --git a/litex/gen/util/__init__.py b/litex/gen/util/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/litex/gen/util/misc.py b/litex/gen/util/misc.py
deleted file mode 100644 (file)
index ff2240b..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-from fractions import gcd
-import collections
-
-
-def flat_iteration(l):
-    for element in l:
-        if isinstance(element, collections.Iterable):
-            for element2 in flat_iteration(element):
-                yield element2
-        else:
-            yield element
-
-
-def xdir(obj, return_values=False):
-    for attr in dir(obj):
-        if attr[:2] != "__" and attr[-2:] != "__":
-            if return_values:
-                yield attr, getattr(obj, attr)
-            else:
-                yield attr
-
-
-def gcd_multiple(numbers):
-    l = len(numbers)
-    if l == 1:
-        return numbers[0]
-    else:
-        s = l//2
-        return gcd(gcd_multiple(numbers[:s]), gcd_multiple(numbers[s:]))
index 7d590c84bb62dc62a1a74f34f0e5698f3d475926..e4d6e697b462623e338b5cb8a444f30ca89c6540 100644 (file)
@@ -1,6 +1,6 @@
 import os
 
-from litex.gen import *
+from migen import *
 
 from litex.soc.interconnect import wishbone
 
index 8511fff5f7dd71589756751b78dca709452990ff..f2036d810e97015b0ad8d82f2b852ecfa9095e4e 100644 (file)
@@ -1,6 +1,6 @@
 import os
 
-from litex.gen import *
+from migen import *
 
 from litex.soc.interconnect import wishbone
 
index 3027882a0a90208c3b1a36988f7dddce2ddfd816..fa6e0c087dabd9ed0c19725badd02503884a92cb 100644 (file)
@@ -1,5 +1,5 @@
-from litex.gen import *
-from litex.gen.genlib.fsm import FSM, NextState
+from migen import *
+from migen.genlib.fsm import FSM, NextState
 
 from litex.soc.interconnect import wishbone
 
index 69b86004bf1454e0efc0c956f026e158806534c4..289ef39b2a3b1cca4b8a6e88932a421930c68a5c 100644 (file)
@@ -1,5 +1,5 @@
-from litex.gen import *
-from litex.gen.genlib.misc import timeline
+from migen import *
+from migen.genlib.misc import timeline
 
 from litex.soc.interconnect import wishbone
 from litex.soc.interconnect.csr import AutoCSR, CSRStorage, CSRStatus
index 463e1e20c178b9cafa9e20c3159d0ad99f44b4fa..89ccd54d3b219a89b649e0332e7049fea92526f8 100644 (file)
@@ -1,5 +1,5 @@
-from litex.gen import *
-from litex.gen.genlib.cdc import MultiReg
+from migen import *
+from migen.genlib.cdc import MultiReg
 
 from litex.soc.interconnect.csr import *
 
index 5baedca15e02e4f6e246be2652433c035da2afbd..c63840b9a9e18c4438130af72712db382b7e0a88 100644 (file)
@@ -1,4 +1,4 @@
-from litex.gen import *
+from migen import *
 
 
 class Identifier(Module):
index 7a9b26c871c2b945c594a9cedd787968014afbb1..06fc10da9ad8b97c0fceb57c04e15810efd89ae2 100644 (file)
@@ -1,7 +1,7 @@
-from litex.gen import *
-from litex.gen.genlib.roundrobin import *
-from litex.gen.genlib.fsm import FSM, NextState
-from litex.gen.genlib.fifo import SyncFIFO
+from migen import *
+from migen.genlib.roundrobin import *
+from migen.genlib.fsm import FSM, NextState
+from migen.genlib.fifo import SyncFIFO
 
 from litex.soc.cores.sdram.lasmicon.multiplexer import *
 
index a6625015fd8ba45e72b06cf9df5160051fac4e37..dc358b60b43c24ec424b24013923dfb9f581fa3a 100644 (file)
@@ -1,4 +1,4 @@
-from litex.gen import *
+from migen import *
 
 from litex.soc.interconnect import dfi, lasmi_bus
 from litex.soc.cores.sdram.lasmicon.refresher import *
index af118c502f4e2f1a3b1f0ce082dcc5c42c7e001b..66987e07c9478550997c635d8e09e896f80cf8c7 100644 (file)
@@ -1,9 +1,9 @@
 from functools import reduce
 from operator import or_, and_
 
-from litex.gen import *
-from litex.gen.genlib.roundrobin import *
-from litex.gen.genlib.fsm import FSM, NextState
+from migen import *
+from migen.genlib.roundrobin import *
+from migen.genlib.fsm import FSM, NextState
 
 from litex.soc.cores.sdram.lasmicon.perf import Bandwidth
 from litex.soc.interconnect.csr import AutoCSR
index dbd62d3a64c1b2a819f874eff2efe8bc1dbca73e..1e86285e1f1569f77ecaba6d3568728f85eaf508 100644 (file)
@@ -1,4 +1,4 @@
-from litex.gen import *
+from migen import *
 
 from litex.soc.interconnect.csr import *
 
index e4c5da92c2950a7c15dfc3ff0a397becaa40ad36..5de9b35d922e690ea8a72b1fc9334b0adb7e9234 100644 (file)
@@ -1,6 +1,6 @@
-from litex.gen import *
-from litex.gen.genlib.misc import timeline
-from litex.gen.genlib.fsm import FSM
+from migen import *
+from migen.genlib.misc import timeline
+from migen.genlib.fsm import FSM
 
 from litex.soc.cores.sdram.lasmicon.multiplexer import *
 
index 13600b7fc34e9489487ec6b15769e9770240cbde..cc5800d08e87fc570fca1ba7084d459239688da8 100644 (file)
@@ -1,9 +1,9 @@
 from functools import reduce
 from operator import or_
 
-from litex.gen import *
-from litex.gen.genlib.fsm import FSM, NextState
-from litex.gen.genlib.misc import WaitTimer
+from migen import *
+from migen.genlib.fsm import FSM, NextState
+from migen.genlib.misc import WaitTimer
 
 from litex.soc.interconnect import dfi as dfibus
 from litex.soc.interconnect import wishbone
index a8792250ae8308bf8c05ef8f46aff38d3be6ba44..7f9a9291034f1ad172f81e94adf714b05b281c90 100644 (file)
@@ -6,8 +6,8 @@
 # TODO:
 # - add $display support to LiteX gen and manage timing violations?
 
-from litex.gen import *
-from litex.gen.fhdl.specials import *
+from migen import *
+from migen.fhdl.specials import *
 from litex.soc.interconnect.dfi import *
 
 from functools import reduce
index 303faeb0b85988c1afcd1feba5af4bebc2c08200..799be7e04312b56b444d596f6769dd280fab8751 100644 (file)
@@ -21,9 +21,9 @@
 # This PHY only supports CAS Latency 2.
 #
 
-from litex.gen import *
-from litex.gen.genlib.record import *
-from litex.gen.fhdl.specials import Tristate
+from migen import *
+from migen.genlib.record import *
+from migen.fhdl.specials import Tristate
 
 from litex.soc.interconnect.dfi import *
 from litex.soc.cores.sdram import settings as sdram_settings
index 385bbc9bb19d96941a40157719351eb82c4c68ab..7bd4df85c52b1a131975e45b2819e6b7db7128e1 100644 (file)
@@ -1,6 +1,6 @@
 # tCK=5ns CL=7 CWL=6
 
-from litex.gen import *
+from migen import *
 
 from litex.soc.interconnect.dfi import *
 from litex.soc.interconnect.csr import *
index dfd3e0a2cc6c773185fbb55845a63047e555f907..4781736e1844842ffce07bcfcdf8443d5eb6d9c2 100644 (file)
@@ -19,8 +19,8 @@
 from functools import reduce
 from operator import or_
 
-from litex.gen import *
-from litex.gen.genlib.record import *
+from migen import *
+from migen.genlib.record import *
 
 from litex.soc.interconnect.dfi import *
 from litex.soc.cores.sdram import settings as sdram_settings
index 0e99ac12c8d2548a07b503044f7ced4e8e4e7b0b..ce575a4aba1e6dc4866bfb5068b81087ba8f4d5c 100644 (file)
@@ -1,7 +1,7 @@
 from math import ceil
 from collections import namedtuple
 
-from litex.gen import *
+from migen import *
 
 
 PhySettingsT = namedtuple("PhySettings", "memtype dfi_databits nphases rdphase wrphase rdcmdphase wrcmdphase cl cwl read_latency write_latency")
index 28b0318e45f01bbe251b68258c337a0b180840c2..6036bff9bf1b3874a4a9e0e90790ada230bb9789 100644 (file)
@@ -1,7 +1,7 @@
 from functools import reduce
 from operator import xor
 
-from litex.gen import *
+from migen import *
 
 from litex.soc.interconnect.csr import *
 from litex.soc.interconnect import dma_lasmi
@@ -114,8 +114,8 @@ class _LFSRTB(Module):
         print("{0:032x}".format(selfp.dut.o))
 
 if __name__ == "__main__":
-    from litex.gen.fhdl import verilog
-    from litex.gen.sim.generic import run_simulation
+    from migen.fhdl import verilog
+    from migen.sim.generic import run_simulation
 
     lfsr = LFSR(3, 4, [3, 2])
     print(verilog.convert(lfsr, ios={lfsr.ce, lfsr.reset, lfsr.o}))
index 56db5020d84ab35a8f1a9bad3878c1e636df465c..1658d949cad088fdce29c88b4d26ad1f7daadf37 100644 (file)
@@ -1,6 +1,6 @@
-from litex.gen import *
-from litex.gen.bank.description import *
-from litex.gen.genlib.fsm import FSM, NextState
+from migen import *
+from migen.bank.description import *
+from migen.genlib.fsm import FSM, NextState
 
 
 class SPIMaster(Module, AutoCSR):
index bed69b1442f7ec6e5f2319e613879dc952e365d9..065600833ebfbe408343a825b9072d4e48a0bcc0 100644 (file)
@@ -1,6 +1,6 @@
-from litex.gen import *
-from litex.gen.genlib.record import *
-from litex.gen.sim.generic import run_simulation
+from migen import *
+from migen.genlib.record import *
+from migen.sim.generic import run_simulation
 
 from litex.soc.com.spi import SPIMaster
 
index d98a85e953ab7c212e7c5cbb776819cb28d7d531..fdfefde2d4c71d62f2cacd6e8a32d8a0042ce5df 100644 (file)
@@ -1,4 +1,4 @@
-from litex.gen import *
+from migen import *
 
 from litex.soc.interconnect.csr import *
 from litex.soc.interconnect.csr_eventmanager import *
index d394f5aa7702de64b1bb3fd618a91e4c9e912507..ee6075cc0a389e01f796f0dc5d5c682a7c8399c1 100644 (file)
@@ -1,6 +1,6 @@
-from litex.gen import *
-from litex.gen.genlib.record import Record
-from litex.gen.genlib.cdc import MultiReg
+from migen import *
+from migen.genlib.record import Record
+from migen.genlib.cdc import MultiReg
 
 from litex.soc.interconnect.csr import *
 from litex.soc.interconnect.csr_eventmanager import *
index 4648b1b8788f0880cbd508e492c9a60f043e7e4d..636e305e8a65f405485cde0e7aa15079f16d0a03 100644 (file)
@@ -1,4 +1,4 @@
-from litex.gen import *
+from migen import *
 
 from litex.soc.interconnect.csr import CSRStatus
 
index 1f73c1ecbb0095c5662060f84981644c5e3f1b09..8ca1db005f8b5397e090e500c2126eef01600234 100644 (file)
@@ -1,4 +1,4 @@
-from litex.gen import log2_int
+from migen import log2_int
 
 
 def get_sdram_phy_header(sdram_phy_settings):
index 4f55e9c0cf7940df3b2fae7f14850b2b4da9da52..86eb958f650e62f44a7b4862c579a71b434c774f 100644 (file)
@@ -1,6 +1,6 @@
 from operator import itemgetter
 
-from litex.gen import *
+from migen import *
 
 from litex.soc.cores import identifier, timer, uart
 from litex.soc.cores.cpu import lm32, mor1kx
index 3c3a3e836107d44b0e76e6941c90de47c9c9d9b7..8967657f85eb46954468bae50529096399dd886b 100644 (file)
@@ -1,5 +1,5 @@
-from litex.gen import *
-from litex.gen.genlib.record import *
+from migen import *
+from migen.genlib.record import *
 
 from litex.soc.interconnect import wishbone, wishbone2lasmi, lasmi_bus
 from litex.soc.interconnect.csr import AutoCSR
@@ -84,7 +84,7 @@ class SoCSDRAM(SoCCore):
                 # Remove this workaround when fixed by Xilinx.
                 from litex.build.xilinx.vivado import XilinxVivadoToolchain
                 if isinstance(self.platform.toolchain, XilinxVivadoToolchain):
-                    from litex.gen.fhdl.simplify import FullMemoryWE
+                    from migen.fhdl.simplify import FullMemoryWE
                     self.submodules.l2_cache = FullMemoryWE()(l2_cache)
                 else:
                     self.submodules.l2_cache = l2_cache
@@ -97,7 +97,7 @@ class SoCSDRAM(SoCCore):
                 # Remove this workaround when fixed by Xilinx.
                 from litex.build.xilinx.vivado import XilinxVivadoToolchain
                 if isinstance(self.platform.toolchain, XilinxVivadoToolchain):
-                    from litex.gen.fhdl.simplify import FullMemoryWE
+                    from migen.fhdl.simplify import FullMemoryWE
                     self.submodules.l2_cache = FullMemoryWE()(l2_cache)
                 else:
                     self.submodules.l2_cache = l2_cache
index c4458cdeb327516b5e3aa27c82c469eefd40b2d5..8183b2e01a54a75a9e6522390b79254213c6168f 100644 (file)
@@ -1,6 +1,6 @@
-from litex.gen import *
-from litex.gen.util.misc import xdir
-from litex.gen.fhdl.tracer import get_obj_var_name
+from migen import *
+from migen.util.misc import xdir
+from migen.fhdl.tracer import get_obj_var_name
 
 
 class _CSRBase(DUID):
index 1281992753eba3395989c39caecbee259932060b..5e21d8dca9aad1e75b398808ba897abb77a09776 100644 (file)
@@ -1,7 +1,7 @@
-from litex.gen import *
-from litex.gen.genlib.record import *
-from litex.gen.genlib.misc import chooser
-from litex.gen.util.misc import xdir
+from migen import *
+from migen.genlib.record import *
+from migen.genlib.misc import chooser
+from migen.util.misc import xdir
 
 from litex.soc.interconnect import csr
 from litex.soc.interconnect.csr import CSRStorage
index 12b85a0a94f2a6bb1714c6aef6600d5e4752227f..56258ff7dee88b378b1aeb2f835ca9fa33fc9d0b 100644 (file)
@@ -1,8 +1,8 @@
 from functools import reduce
 from operator import or_
 
-from litex.gen import *
-from litex.gen.util.misc import xdir
+from migen import *
+from migen.util.misc import xdir
 
 from litex.soc.interconnect.csr import *
 
index 25812122e32f51b19e81c74f6d4cf2f723b049c8..aae56b0d380075f0403fa0f2bbd7bb90f333e7ae 100644 (file)
@@ -1,5 +1,5 @@
-from litex.gen import *
-from litex.gen.genlib.record import *
+from migen import *
+from migen.genlib.record import *
 
 
 def phase_cmd_description(addressbits, bankbits):
index 1d1e99984e750f38bce0dc38e0f0fb7c9c0ba61e..ce3937bc7396c5b6803e371f16f04d935a01664b 100644 (file)
@@ -1,5 +1,5 @@
-from litex.gen import *
-from litex.gen.genlib.fifo import SyncFIFO
+from migen import *
+from migen.genlib.fifo import SyncFIFO
 
 
 class Reader(Module):
index 841b72b16bd0fed190497ad018b5a76571d57bd4..c8d2ded262acb235ca34cba17d831a2f27a6928f 100644 (file)
@@ -1,9 +1,9 @@
 from functools import reduce
 from operator import or_
 
-from litex.gen import *
-from litex.gen.genlib import roundrobin
-from litex.gen.genlib.record import *
+from migen import *
+from migen.genlib import roundrobin
+from migen.genlib.record import *
 
 
 class Interface(Record):
index a1b44c2e76a6571d0caa0dff4fbf3cfc853d9703..0c70842039de8551f490b128efa988268b9148ae 100644 (file)
@@ -1,6 +1,6 @@
-from litex.gen import *
-from litex.gen.genlib.record import *
-from litex.gen.genlib import fifo
+from migen import *
+from migen.genlib.record import *
+from migen.genlib import fifo
 
 
 def _make_m2s(layout):
@@ -154,7 +154,7 @@ class Demultiplexer(Module):
 # XXX
 
 from copy import copy
-from litex.gen.util.misc import xdir
+from migen.util.misc import xdir
 
 def pack_layout(l, n):
     return [("chunk"+str(i), l) for i in range(n)]
index c10cda4eec868e244303aaa5b13ffa4e8943eae9..5b51431a2ffc461c77ef230dff6095d21681abd5 100644 (file)
@@ -1,11 +1,11 @@
 from functools import reduce
 from operator import or_
 
-from litex.gen import *
-from litex.gen.genlib import roundrobin
-from litex.gen.genlib.record import *
-from litex.gen.genlib.misc import split, displacer, chooser
-from litex.gen.genlib.fsm import FSM, NextState
+from migen import *
+from migen.genlib import roundrobin
+from migen.genlib.record import *
+from migen.genlib.misc import split, displacer, chooser
+from migen.genlib.fsm import FSM, NextState
 
 from litex.soc.interconnect import csr
 
index 25efdc6fdf9f47b421f109a99f2781c13632d039..1d7171a31d75106c0060d64042e81a8c851a888e 100644 (file)
@@ -1,5 +1,5 @@
-from litex.gen import *
-from litex.gen.genlib.misc import timeline
+from migen import *
+from migen.genlib.misc import timeline
 
 from litex.soc.interconnect import csr_bus, wishbone
 
index bd139afa3ba820a93d783e861ac91b77593af68b..9c95689c495410297b361b053ad806997aabb7b4 100644 (file)
@@ -1,5 +1,5 @@
-from litex.gen import *
-from litex.gen.genlib.fsm import FSM, NextState
+from migen import *
+from migen.genlib.fsm import FSM, NextState
 
 
 class WB2LASMI(Module):