Exemple #1
0
def toSimModel(unit, targetPlatform=DummyPlatform(), dumpModelIn=None):
    """
    Create a simulation model for unit

    :param unit: interface level unit which you wont prepare for simulation
    :param targetPlatform: target platform for this synthes
    :param dumpModelIn: folder to where put sim model files
        (otherwise sim model will be constructed only in memory)
    """
    sim_code = toRtl(unit,
                     targetPlatform=targetPlatform,
                     saveTo=dumpModelIn,
                     serializer=SimModelSerializer)
    if dumpModelIn is not None:
        d = os.path.join(os.getcwd(), dumpModelIn)
        dInPath = d in sys.path
        if not dInPath:
            sys.path.insert(0, d)
        if unit._name in sys.modules:
            del sys.modules[unit._name]
        simModule = importlib.import_module(unit._name)

        if not dInPath:
            sys.path.remove(d)
    else:
        simModule = ModuleType('simModule')
        # python supports only ~100 opened brackets
        # it exceded it throws MemoryError: s_push: parser stack overflow
        exec(sim_code, simModule.__dict__)

    return simModule.__dict__[unit._name]
Exemple #2
0
    def compileSim(cls, unit, build_dir: Optional[str]=DEFAULT_BUILD_DIR,
                   unique_name: Optional[str]=None, onAfterToRtl=None,
                   target_platform=DummyPlatform()):
        """
        Create simulation model and connect it with interfaces of original unit
        and decorate it with agents

        :param unit: interface level unit which you wont prepare for simulation
        :param target_platform: target platform for this synthesis
        :param build_dir: folder to where to put sim model files,
            if None temporary folder is used and then deleted
            (or simulator will be constructed in memory if possible)
        :param unique_name: name which is used as name of the module for simulation
            (if is None it is automatically generated)
        :param onAfterToRtl: callback fn(unit) which will be called
            after unit will be synthesised to RTL
            and before Unit instance signals are replaced
            with simulator specific ones
        """
        if unique_name is None:
            unique_name = cls.get_unique_name(unit)

        cls.rtl_simulator_cls = toBasicSimulatorSimModel(# toVerilatorSimModel(
            unit,
            unique_name=unique_name,
            build_dir=build_dir,
            target_platform=target_platform,
            do_compile=cls.RECOMPILE)

        if onAfterToRtl:
            onAfterToRtl(unit)

        cls.u = unit
Exemple #3
0
    def test_indexOps(self):
        c, interf = IndexOps()
        _, arch = list(c.synthesize("indexOps", interf, DummyPlatform()))

        s = VhdlSerializer.Architecture(arch, VhdlSerializer.getBaseContext())

        self.assertNotIn("sig_", s)
Exemple #4
0
    def build(cls,
              unit: Unit,
              unique_name: str,
              build_dir: Optional[str],
              target_platform=DummyPlatform(),
              do_compile=True) -> "BasicRtlSimulatorVcd":
        """
        Create a pycocotb.basic_hdl_simulator based simulation model
        for specified unit and load it to python

        :param unit: interface level unit which you wont prepare for simulation
        :param unique_name: unique name for build directory and python module with simulator
        :param target_platform: target platform for this synthesis
        :param build_dir: directory to store sim model build files,
            if None sim model will be constructed only in memory
        """
        if unique_name is None:
            unique_name = unit._getDefaultName()

        _filter = SerializerFilterDoNotExclude()
        if build_dir is None or not do_compile:
            buff = StringIO()
            store_man = SaveToStream(SimModelSerializer, buff, _filter=_filter)
        else:
            if not os.path.isabs(build_dir):
                build_dir = os.path.join(os.getcwd(), build_dir)
            build_private_dir = os.path.join(build_dir, unique_name)
            store_man = SaveToFilesFlat(SimModelSerializer,
                                        build_private_dir,
                                        _filter=_filter)
            store_man.module_path_prefix = unique_name

        to_rtl(unit,
               name=unique_name,
               target_platform=target_platform,
               store_manager=store_man)

        if build_dir is not None:
            d = build_dir
            dInPath = d in sys.path
            if not dInPath:
                sys.path.insert(0, d)
            if unique_name in sys.modules:
                del sys.modules[unique_name]
            simModule = importlib.import_module(
                unique_name + "." + unique_name,
                package='simModule_' + unique_name)

            if not dInPath:
                sys.path.pop(0)
        else:
            simModule = ModuleType('simModule_' + unique_name)
            # python supports only ~100 opened brackets
            # if exceeded it throws MemoryError: s_push: parser stack overflow
            exec(buff.getvalue(), simModule.__dict__)

        model_cls = simModule.__dict__[unit._name]
        # can not use just function as it would get bounded to class
        return cls(model_cls, unit)
Exemple #5
0
def synthesised(u: Unit, targetPlatform=DummyPlatform()):
    assert not u._wasSynthetised()
    if not hasattr(u, "_interfaces"):
        u._loadDeclarations()

    for _ in u._toRtl(targetPlatform):
        pass
    return u
Exemple #6
0
def to_rtl_str(unit_or_cls: Unit,
               serializer_cls=Vhdl2008Serializer,
               name: str = None,
               target_platform=DummyPlatform()):
    buff = StringIO()
    store_manager = SaveToStream(serializer_cls, buff)
    to_rtl(unit_or_cls, store_manager, name, target_platform)
    return buff.getvalue()
Exemple #7
0
def serializeAsIpcore(unit, folderName=".", name=None,
                      serializer: GenericSerializer=VhdlSerializer,
                      targetPlatform=DummyPlatform()):
    from hwt.serializer.ip_packager import IpPackager
    p = IpPackager(unit, name=name,
                   serializer=serializer,
                   targetPlatform=targetPlatform)
    p.createPackage(folderName)
    return p
Exemple #8
0
def netlistToVhdlStr(name, netlist, interfaces):
    for s in interfaces:
        s._interface = True

    ctx = VhdlSerializer.getBaseContext()
    return "\n".join([
        VhdlSerializer.asHdl(o, ctx)
        for o in netlist.synthesize(name, interfaces, DummyPlatform())
    ])
Exemple #9
0
    def build(cls,
              unit: Unit,
              unique_name: str,
              build_dir: Optional[str],
              target_platform=DummyPlatform(),
              do_compile=True):
        """
        Create a verilator based simulation model for specified unit
        and load it to Python

        :param unit: interface level unit which you wont prepare for simulation
        :param unique_name: unique name for build directory and python module
            with simulator
        :param target_platform: target platform for this synthesis
        :param build_dir: directory to store sim model build files,
            if None temporary folder is used and then deleted
        :param do_compile: if false reuse existing build if exists [TODO]
        """
        if build_dir is None:
            build_dir = os.path.join("tmp", unique_name)

        build_private_dir = os.path.join(os.getcwd(), build_dir, unique_name)
        store_man = SaveToFilesFlat(VerilogSerializer,
                                    build_private_dir,
                                    _filter=SerializerFilterDoNotExclude())

        to_rtl(unit,
               name=unique_name,
               target_platform=target_platform,
               store_manager=store_man)
        sim_verilog = store_man.files

        accessible_signals = collect_signals(unit)
        used_names = {x[0] for x in accessible_signals}
        assert len(used_names) == len(accessible_signals), \
            "All signal has to have unique names"
        if do_compile:
            verilatorCompile(sim_verilog, build_dir)

            sim_so = generatePythonModuleWrapper(unit._name, unique_name,
                                                 build_dir, accessible_signals)
        else:
            sim_so = None
            file_pattern = './**/{0}.*.so'.format(unique_name)
            for filename in iglob(file_pattern, recursive=True):
                assert sim_so is None, ("Can not resolve simulation library",
                                        sim_so, filename)
                sim_so = filename

        # load compiled library into python
        sim_module = loadPythonCExtensionFromFile(sim_so, unique_name)
        sim_cls = getattr(sim_module, unique_name)

        return sim_cls
Exemple #10
0
def synthesised(u: Unit, target_platform=DummyPlatform()):
    """
    Elaborate design without producing any HDL
    """
    sm = StoreManager(DummySerializerConfig,
                      _filter=SerializerFilterDoNotExclude())
    if not hasattr(u, "_interfaces"):
        u._loadDeclarations()

    for _ in u._to_rtl(target_platform, sm):
        pass
    return u
Exemple #11
0
def serializeAsIpcore(unit, folderName=".", name=None,
                      serializer_cls=Vhdl2008Serializer,
                      target_platform=DummyPlatform()):
    """
    Create an IPCore package
    """
    from hwt.serializer.ip_packager import IpPackager
    p = IpPackager(unit, name=name,
                   serializer_cls=serializer_cls,
                   target_platform=target_platform)
    p.createPackage(folderName)
    return p
Exemple #12
0
def toBasicSimulatorSimModel(unit: Unit,
                             unique_name: str,
                             build_dir: Optional[str],
                             target_platform=DummyPlatform(),
                             do_compile=True):
    """
    Create a pycocotb.basic_hdl_simulator based simulation model
    for specified unit and load it to python

    :param unit: interface level unit which you wont prepare for simulation
    :param unique_name: unique name for build directory and python module with simulator
    :param target_platform: target platform for this synthesis
    :param build_dir: directory to store sim model build files,
        if None sim model will be constructed only in memory
    """
    if unique_name is None:
        unique_name = unit._getDefaultName()

    if build_dir is not None:
        build_private_dir = os.path.join(os.getcwd(), build_dir, unique_name)
    else:
        build_private_dir = None

    sim_code = toRtl(unit,
                     name=unique_name,
                     targetPlatform=target_platform,
                     saveTo=build_private_dir,
                     serializer=SimModelSerializer)

    if build_dir is not None:
        d = os.path.join(os.getcwd(), build_dir)
        dInPath = d in sys.path
        if not dInPath:
            sys.path.insert(0, d)
        if unique_name in sys.modules:
            del sys.modules[unique_name]
        simModule = importlib.import_module(unique_name + "." + unique_name,
                                            package='simModule_' + unique_name)

        if not dInPath:
            sys.path.pop(0)
    else:
        simModule = ModuleType('simModule_' + unique_name)
        # python supports only ~100 opened brackets
        # if exceded it throws MemoryError: s_push: parser stack overflow
        exec(sim_code, simModule.__dict__)

    model_cls = simModule.__dict__[unit._name]
    # can not use just function as it would get bounded to class
    return BasicSimConstructor(model_cls, unit)
Exemple #13
0
def to_rtl(unit_or_cls: Unit,
           store_manager: StoreManager,
           name: str = None,
           target_platform=DummyPlatform()):
    """
    Convert unit to RTL using specified serializer

    :param unitOrCls: unit instance or class, which should be converted
    :param name: name override of top unit (if is None name is derived
        form class name)
    :param target_platform: meta-informations about target platform, distributed
        on every unit under _target_platform attribute
        before Unit._impl() is called
    """
    if isinstance(unit_or_cls, Unit):
        u = unit_or_cls
    else:
        u = unit_or_cls()

    u._target_platform = target_platform
    u._store_manager = store_manager
    u._loadDeclarations()
    if name is not None:
        assert isinstance(name, str)
        u._hdl_module_name = u._name = name

    # serialize all unit instances to HDL code
    constraints = HdlConstraintList()
    for _, obj in u._to_rtl(target_platform, store_manager):
        # collect constraints directly in current component
        constraints.extend(obj._constraints)

        if obj._shared_component_with:
            # if the instance is shared with something else make
            # the paths in constraints relative to a component
            path_old = _get_absolute_path(obj._shared_component_with[0])
            path_new = _get_absolute_path(obj)

            for c in _Unit_constraints_copy_recursively(
                    obj, path_old, path_new):
                constraints.append(c)

    if constraints:
        # serialize all constraints in design
        store_manager.write(constraints)

    return store_manager
Exemple #14
0
def toVerilatorSimModel(unit: Unit,
                        unique_name: str,
                        build_dir: Optional[str],
                        target_platform=DummyPlatform(),
                        do_compile=True):
    """
    Create a verilator based simulation model for specified unit
    and load it to Python

    :param unit: interface level unit which you wont prepare for simulation
    :param unique_name: unique name for build directory and python module
        with simulator
    :param target_platform: target platform for this synthesis
    :param build_dir: directory to store sim model build files,
        if None temporary folder is used and then deleted
    :param do_compile: if false reuse existing build if exists [TODO]
    """
    if build_dir is None:
        build_dir = "tmp/%s" % unique_name

    # with tempdir(suffix=unique_name) as build_dir:
    sim_verilog = toRtl(unit,
                        targetPlatform=target_platform,
                        saveTo=build_dir,
                        serializer=VerilogForVerilatorSerializer)
    accessible_signals = collect_signals(unit)
    used_names = {x[0] for x in accessible_signals}
    assert len(used_names) == len(accessible_signals), \
        "All signal has to have unique names"
    if do_compile:
        verilatorCompile(sim_verilog, build_dir)

        sim_so = generatePythonModuleWrapper(unit._name, unique_name,
                                             build_dir, accessible_signals)
    else:
        sim_so = None
        file_pattern = './**/{0}.*.so'.format(unique_name)
        for filename in iglob(file_pattern, recursive=True):
            assert sim_so is None, ("Can not resolve simulation library",
                                    sim_so, filename)
            sim_so = filename

    # load compiled library into python
    sim_module = loadPythonCExtensionFromFile(sim_so, unique_name)
    sim_cls = getattr(sim_module, unique_name)

    return sim_cls
Exemple #15
0
def netlistToVhdlStr(name: str, netlist: RtlNetlist,
                     interfaces: Dict[RtlSignal, DIRECTION]):
    name_scope = NameScope(None, name, True)
    buff = StringIO()
    store_manager = SaveToStream(Vhdl2008Serializer, buff)
    netlist.create_HdlModuleDec(name, store_manager, {})
    netlist.interfaces = interfaces
    for s, d in interfaces.items():
        s._interface = True
        pi = portItemfromSignal(s, netlist, d)
        # port of current top component
        s.name = name_scope.checked_name(s.name, s)
        pi.connectInternSig(s)
        netlist.ent.ports.append(pi)
    netlist.ent.ports.sort(key=lambda x: x.name)
    netlist.create_HdlModuleDef(DummyPlatform(), store_manager)
    store_manager.write(netlist.arch)
    return buff.getvalue()
Exemple #16
0
 def compileSimAndStart(
         self,
         unit: Unit,
         build_dir: Optional[str]=DEFAULT_BUILD_DIR,
         unique_name: Optional[str]=None,
         onAfterToRtl=None,
         target_platform=DummyPlatform()):
     """
     Use this method if you did not used compileSim()
     or SingleUnitSimTestCase to setup the simulator and DUT
     """
     if unique_name is None:
         unique_name = "%s__%s" % (self.getTestName(),
                                   unit._getDefaultName())
     self.compileSim(unit, build_dir, unique_name,
                     onAfterToRtl, target_platform)
     self.u = unit
     SimTestCase.setUp(self)
     return self.u
Exemple #17
0
    def prepareUnit(self, unit, modelCls=None, dumpModelIn=None,
                    onAfterToRtl=None, targetPlatform=DummyPlatform()):
        """
        Create simulation model and connect it with interfaces of original unit
        and decorate it with agents and collect all simulation processes

        :param unit: interface level unit which you wont prepare for simulation
        :param modelCls: class of rtl simulation model to run simulation on,
            if is None rtl sim model will be generated from unit
        :param dumpModelIn: folder to where put sim model files (if is None
            sim model will be constructed only in memory)
        :param onAfterToRtl: callback fn(unit) which will be called unit after
            it will be synthesised to rtl
        """
        self.u, self.model, self.procs = simPrepare(
            unit,
            modelCls=modelCls,
            targetPlatform=targetPlatform,
            dumpModelIn=dumpModelIn,
            onAfterToRtl=onAfterToRtl)
Exemple #18
0
    def __init__(self, topUnit: Unit, name: str=None,
                 extra_files: List[str]=[],
                 serializer_cls=Vhdl2008Serializer,
                 target_platform=DummyPlatform()):
        """
        :param topObj: :class:`hwt.synthesizer.unit.Unit` instance of top component
        :param name: optional name of top
        :param extra_files: list of extra HDL/constrain file names for files
            which should be distributed in this IP-core
            (\*.v - verilog, \*.sv,\*.svh -system verilog, \*.vhd - vhdl, \*.xdc - XDC)
        :param serializer: serializer which specifies target HDL language
        :param target_platform: specifies properties of target platform, like available resources, vendor, etc.
        """
        if not name:
            name = topUnit._getDefaultName()

        super(IpPackager, self).__init__(
            topUnit, name, extra_files)
        self.serializer = serializer_cls
        self.target_platform = target_platform
Exemple #19
0
    def __init__(self, topUnit: Unit, name: str=None,
                 extraVhdlFiles: List[str]=[],
                 extraVerilogFiles: List[str]=[],
                 serializer=VhdlSerializer,
                 targetPlatform=DummyPlatform()):
        """
        :param topObj: Unit instance of top component
        :param name: optional name of top
        :param extraVhdlFiles: list of extra vhdl file names for files
            which should be distributed in this IP-core
        :param extraVerilogFiles: same as extraVhdlFiles just for Verilog
        :param serializer: serializer which specifies target HDL language
        :param targetPlatform: specifies properties of target platform, like available resources, vendor, etc.
        """
        assert not topUnit._wasSynthetised()
        if not name:
            name = topUnit._getDefaultName()

        super(IpPackager, self).__init__(
            topUnit, name, extraVhdlFiles, extraVerilogFiles)
        self.serializer = serializer
        self.targetPlatform = targetPlatform
Exemple #20
0
def simPrepare(unit: Unit,
               modelCls: Optional[SimModel] = None,
               targetPlatform=DummyPlatform(),
               dumpModelIn: str = None,
               onAfterToRtl=None):
    """
    Create simulation model and connect it with interfaces of original unit
    and decorate it with agents

    :param unit: interface level unit which you wont prepare for simulation
    :param modelCls: class of rtl simulation model to run simulation on,
        if is None rtl sim model will be generated from unit
    :param targetPlatform: target platform for this synthes
    :param dumpModelIn: folder to where put sim model files
        (if is None sim model will be constructed only in memory)
    :param onAfterToRtl: callback fn(unit, modelCls) which will be called
        after unit will be synthesised to rtl

    :return: tuple (fully loaded unit with connected sim model,
        connected simulation model,
        simulation processes of agents
        )
    """
    if modelCls is None:
        modelCls = toSimModel(unit,
                              targetPlatform=targetPlatform,
                              dumpModelIn=dumpModelIn)
    else:
        # to instantiate hierarchy of unit
        toSimModel(unit)

    if onAfterToRtl:
        onAfterToRtl(unit, modelCls)

    reconnectUnitSignalsToModel(unit, modelCls)
    model = modelCls()
    procs = autoAddAgents(unit)
    return unit, model, procs
Exemple #21
0
    def __init__(self,
                 topUnit: Unit,
                 name: str = None,
                 extraVhdlFiles: List[str] = [],
                 extraVerilogFiles: List[str] = [],
                 serializer=VhdlSerializer,
                 targetPlatform=DummyPlatform()):
        assert not topUnit._wasSynthetised()
        self.topUnit = topUnit
        self.serializer = serializer
        self.targetPlatform = targetPlatform
        if name:
            self.name = name
        else:
            self.name = self.topUnit._getDefaultName()

        self.hdlFiles = UniqList()

        for f in extraVhdlFiles:
            self.hdlFiles.append(f)

        for f in extraVerilogFiles:
            self.hdlFiles.append(f)
Exemple #22
0
def toRtl(unitOrCls: Unit, name: str=None,
          serializer: GenericSerializer=VhdlSerializer,
          targetPlatform=DummyPlatform(), saveTo: str=None):
    """
    Convert unit to RTL using specified serializer

    :param unitOrCls: unit instance or class, which should be converted
    :param name: name override of top unit (if is None name is derived
        form class name)
    :param serializer: serializer which should be used for to RTL conversion
    :param targetPlatform: metainformatins about target platform, distributed
        on every unit under _targetPlatform attribute
        before Unit._impl() is called
    :param saveTo: directory where files should be stored
        If None RTL is returned as string.
    :raturn: if saveTo returns RTL string else returns list of file names
        which were created
    """
    if not isinstance(unitOrCls, Unit):
        u = unitOrCls()
    else:
        u = unitOrCls

    u._loadDeclarations()
    if name is not None:
        assert isinstance(name, str)
        u._name = name

    globScope = serializer.getBaseNameScope()
    mouduleScopes = {}

    # unitCls : unitobj
    serializedClasses = {}

    # (unitCls, paramsValues) : unitObj
    # where paramsValues are dict name:value
    serializedConfiguredUnits = {}

    doSerialize = True

    createFiles = saveTo is not None
    if createFiles:
        os.makedirs(saveTo, exist_ok=True)
        files = UniqList()
    else:
        codeBuff = []

    for obj in u._toRtl(targetPlatform):
        doSerialize = serializer.serializationDecision(
            obj,
            serializedClasses,
            serializedConfiguredUnits)
        if doSerialize:
            if isinstance(obj, Entity):
                s = globScope.fork(1)
                s.setLevel(2)
                ctx = serializer.getBaseContext()
                ctx.scope = s
                mouduleScopes[obj] = ctx
                ctx.currentUnit = obj.origin

                sc = serializer.Entity(obj, ctx)
                if createFiles:
                    fName = obj.name + serializer.fileExtension
                    fileMode = 'w'

            elif isinstance(obj, Architecture):
                try:
                    ctx = mouduleScopes[obj.entity]
                except KeyError:
                    raise SerializerException(
                        "Entity should be serialized"
                        " before architecture of %s"
                        % (obj.getEntityName()))

                sc = serializer.Architecture(obj, ctx)
                if createFiles:
                    fName = obj.getEntityName() + serializer.fileExtension
                    fileMode = 'a'
            else:
                if hasattr(obj, "_hdlSources"):
                    for fn in obj._hdlSources:
                        if isinstance(fn, str):
                            shutil.copy2(fn, saveTo)
                            files.append(fn)
                            continue
                else:
                    sc = serializer.asHdl(obj)

            if sc:
                if createFiles:
                    fp = os.path.join(saveTo, fName)
                    files.append(fp)
                    with open(fp, fileMode) as f:
                        if fileMode == 'a':
                            f.write("\n")

                        f.write(
                            serializer.formatter(sc)
                        )
                else:
                    codeBuff.append(sc)

        elif not createFiles:
            try:
                name = '"%s"' % obj.name
            except AttributeError:
                name = ""
            codeBuff.append(serializer.comment(
                "Object of class %s, %s was not serialized as specified" % (
                    obj.__class__.__name__, name)))

    if createFiles:
        return files
    else:
        return serializer.formatter(
            "\n".join(codeBuff)
        )
Exemple #23
0
from hwt.synthesizer.dummyPlatform import DummyPlatform
from hwtGraph.elk.fromHwt.extractSplits import extractSplits
from hwtGraph.elk.fromHwt.flattenTrees import flattenTrees
from hwtGraph.elk.fromHwt.mergeSplitsOnInterfaces import mergeSplitsOnInterfaces
from hwtGraph.elk.fromHwt.netlistPreprocessors import unhideResultsOfIndexingAndConcatOnPublicSignals
from hwtGraph.elk.fromHwt.reduceUselessAssignments import reduceUselessAssignments
from hwtGraph.elk.fromHwt.resolveSharedConnections import resolveSharedConnections
from hwtGraph.elk.fromHwt.sortStatementPorts import sortStatementPorts
from hwtGraph.elk.fromHwt.propagatePresets import propagatePresets

DEFAULT_PLATFORM = DummyPlatform()
DEFAULT_PLATFORM.beforeHdlArchGeneration.extend([
    unhideResultsOfIndexingAndConcatOnPublicSignals,
    propagatePresets,
])

DEFAULT_LAYOUT_OPTIMIZATIONS = [
    # optimizations
    reduceUselessAssignments,
    extractSplits,
    lambda root: flattenTrees(
        root, lambda node: node.cls == "Operator" and node.name == "CONCAT",
        True),
    mergeSplitsOnInterfaces,
    resolveSharedConnections,
    # prettyfications
    sortStatementPorts,
]