<commit_before>from copy import copy

from hwt.code import log2ceil
from hwt.hdlObjects.constants import INTF_DIRECTION
from hwt.hdlObjects.transTmpl import TransTmpl
from hwt.hdlObjects.typeShortcuts import vecT
from hwt.hdlObjects.types.array import Array
from hwt.hdlObjects.types.bits import Bits
from hwt.hdlObjects.types.hdlType import HdlType
from hwt.hdlObjects.types.struct import HStruct
from hwt.hdlObjects.types.structUtils import BusFieldInfo
from hwt.interfaces.std import BramPort_withoutClk, RegCntrl, Signal, VldSynced
from hwt.interfaces.structIntf import StructIntf
from hwt.interfaces.utils import addClkRstn
from hwt.synthesizer.interfaceLevel.interfaceUtils.proxy import InterfaceProxy
from hwt.synthesizer.interfaceLevel.mainBases import InterfaceBase
from hwt.synthesizer.interfaceLevel.unit import Unit
from hwt.synthesizer.interfaceLevel.unitImplHelpers import getSignalName
from hwt.synthesizer.rtlLevel.mainBases import RtlSignalBase
from hwtLib.sim.abstractMemSpaceMaster import PartialField
from hwt.synthesizer.interfaceLevel.interfaceUtils.utils import walkFlatten


def inRange(n, lower, end):
    return (n >= lower) & (n < end)


class BusEndpoint(Unit):
    """
    Abstract unit
    Delegate request from bus to fields of structure
    (fields are represented by various interfaces)
    write has higher priority

    .. aafig::
        +------+    +----------+     +---------+
        | bus  +---->          +-----> field0  |
        |      <----+          <-----+         |
        +------+    |          |     +---------+
                    |          |
                    | endpoint |     +---------+
                    |          +-----> field1  |
                    |          <-----+         |
                    |          |     +---------+
                    |          |
                    |          |     +---------+
                    |          +-----> field2  |
                    |          <-----+         |
                    +----------+     +---------+

    """
    def __init__(self, structTemplate, intfCls=None, shouldEnterFn=None):
        """
        :param structTemplate: instance of HStruct which describes address space of this endpoint
        :param intfCls: class of bus interface which should be used
        :param shouldEnterFn: function(transactionTemplate) which should return true if structuralized type like Array or HStruct
            should be interpreted as separate interfaces or not
        """
        assert intfCls is not None, "intfCls has to be specified"

        self._intfCls = intfCls
        self.STRUCT_TEMPLATE = structTemplate
        if shouldEnterFn is None:
            self.shouldEnterFn = lambda tmpl: not isinstance(tmpl.dtype, Array)
        else:
            self.shouldEnterFn = shouldEnterFn
        Unit.__init__(self)

    def _getWordAddrStep(self):
        raise NotImplementedError("Should be overridden in concrete implementation, this is abstract class")

    def _getAddrStep(self):
        raise NotImplementedError("Should be overridden in concrete implementation, this is abstract class")

    def _config(self):
        self._intfCls._config(self)

    def _declr(self):
        addClkRstn(self)

        with self._paramsShared():
            self.bus = self._intfCls()

        self.decoded = StructIntf(self.STRUCT_TEMPLATE, instantiateFieldFn=self._mkFieldInterface)

    def getPort(self, transTmpl):
        o = transTmpl.origin
        return self.decoded._fieldsToInterfaces[o]

    def isInMyAddrRange(self, addrSig):
        return (addrSig >= self._getMinAddr()) & (addrSig < self._getMaxAddr())

    def walkFieldsAndIntf(self, transTmpl, structIntf):
        fieldTrans = transTmpl.walkFlatten(shouldEnterFn=self.shouldEnterFn)

        def shouldEnterIntf(intf):
            """
            :return: tuple (shouldEnter, shouldYield)
            """
            if isinstance(intf, InterfaceProxy) and intf._itemsInOne == 1:
                if isinstance(intf._origIntf, (RegCntrl, BramPort_withoutClk)):
                    return (False, True)
                else:
                    return (True, False)
            if isinstance(intf, (RegCntrl, BramPort_withoutClk)):
                if intf._widthMultiplier is not None:
                    return (False, False)
                else:
                    return (False, True)
            else:
                return (True, False)

        intfs = walkFlatten(structIntf, shouldEnterIntf)

        for (((base, end), transTmpl), intf) in zip(fieldTrans, intfs):
            if isinstance(intf, InterfaceProxy):
                _tTmpl = copy(transTmpl)
                _tTmpl.bitAddr = base
                _tTmpl.bitAddrEnd = end
                _tTmpl.origin = PartialField(transTmpl.origin)
                transTmpl = _tTmpl

            yield transTmpl, intf

    def _parseTemplate(self):
        self._directlyMapped = []
        self._bramPortMapped = []
        self.ADRESS_MAP = []

        self.WORD_ADDR_STEP = self._getWordAddrStep()
        self.ADDR_STEP = self._getAddrStep()

        def getIndexOfPart(transTmpl):
            index = 0
            parentArray = transTmpl.parent
            while not (isinstance(parentArray.dtype, Array) and parentArray.bitAddrEnd >= transTmpl.bitAddrEnd):
                parentArray = parentArray.parent
                if isinstance(parentArray.dtype, Array):
                    index += (transTmpl.bitAddr - parentArray.bitAddr) // parentArray.getItemWidth()
                    # [FIXME] not working correctly for multi level arrays
            return index

        AW = int(self.ADDR_WIDTH)
        SUGGESTED_AW = self._suggestedAddrWidth()
        assert SUGGESTED_AW <= AW, (SUGGESTED_AW, AW)
        tmpl = TransTmpl(self.STRUCT_TEMPLATE)
        # fieldTrans = tmpl.walkFlatten(shouldEnterFn=self.shouldEnterFn)

        for transTmpl, intf in self.walkFieldsAndIntf(tmpl, self.decoded):
            if isinstance(intf, InterfaceProxy):
                self.decoded._fieldsToInterfaces[transTmpl.origin] = intf
                intfClass = intf._origIntf.__class__
            else:
                intfClass = intf.__class__

            if issubclass(intfClass, RegCntrl):
                self._directlyMapped.append(transTmpl)

            elif issubclass(intfClass, BramPort_withoutClk):
                self._bramPortMapped.append(transTmpl)
            else:
                raise NotImplementedError(intf)

            self.ADRESS_MAP.append(transTmpl)

    def _getMaxAddr(self):
        lastItem = self.ADRESS_MAP[-1]
        return lastItem.bitAddrEnd // self._getAddrStep()

    def _getMinAddr(self):
        return self.ADRESS_MAP[0].bitAddr // self._getAddrStep()

    def _suggestedAddrWidth(self):
        """
        Based on strut template resolve how many bits for
        address is needed
        """
        bitSize = self.STRUCT_TEMPLATE.bit_length()
        wordAddrStep = self._getWordAddrStep()
        addrStep = self._getAddrStep()

        maxAddr = (bitSize // addrStep)

        # align to word size
        if maxAddr % wordAddrStep != 0:
            wordAddrStep += wordAddrStep - (maxAddr % wordAddrStep)

        return maxAddr.bit_length()<commit_msg>BusEndpoint: rm dead code<commit_after>from copy import copy

from hwt.code import log2ceil
from hwt.hdlObjects.constants import INTF_DIRECTION
from hwt.hdlObjects.transTmpl import TransTmpl
from hwt.hdlObjects.typeShortcuts import vecT
from hwt.hdlObjects.types.array import Array
from hwt.hdlObjects.types.bits import Bits
from hwt.hdlObjects.types.hdlType import HdlType
from hwt.hdlObjects.types.struct import HStruct
from hwt.hdlObjects.types.structUtils import BusFieldInfo
from hwt.interfaces.std import BramPort_withoutClk, RegCntrl, Signal, VldSynced
from hwt.interfaces.structIntf import StructIntf
from hwt.interfaces.utils import addClkRstn
from hwt.synthesizer.interfaceLevel.interfaceUtils.proxy import InterfaceProxy
from hwt.synthesizer.interfaceLevel.interfaceUtils.utils import walkFlatten
from hwt.synthesizer.interfaceLevel.mainBases import InterfaceBase
from hwt.synthesizer.interfaceLevel.unit import Unit
from hwt.synthesizer.interfaceLevel.unitImplHelpers import getSignalName
from hwt.synthesizer.rtlLevel.mainBases import RtlSignalBase
from hwtLib.sim.abstractMemSpaceMaster import PartialField


def inRange(n, lower, end):
    return (n >= lower) & (n < end)


class BusEndpoint(Unit):
    """
    Abstract unit
    Delegate request from bus to fields of structure
    (fields are represented by various interfaces)
    write has higher priority

    .. aafig::
        +------+    +----------+     +---------+
        | bus  +---->          +-----> field0  |
        |      <----+          <-----+         |
        +------+    |          |     +---------+
                    |          |
                    | endpoint |     +---------+
                    |          +-----> field1  |
                    |          <-----+         |
                    |          |     +---------+
                    |          |
                    |          |     +---------+
                    |          +-----> field2  |
                    |          <-----+         |
                    +----------+     +---------+

    """
    def __init__(self, structTemplate, intfCls=None, shouldEnterFn=None):
        """
        :param structTemplate: instance of HStruct which describes address space of this endpoint
        :param intfCls: class of bus interface which should be used
        :param shouldEnterFn: function(transactionTemplate) which should return true if structuralized type like Array or HStruct
            should be interpreted as separate interfaces or not
        """
        assert intfCls is not None, "intfCls has to be specified"

        self._intfCls = intfCls
        self.STRUCT_TEMPLATE = structTemplate
        if shouldEnterFn is None:
            self.shouldEnterFn = lambda tmpl: not isinstance(tmpl.dtype, Array)
        else:
            self.shouldEnterFn = shouldEnterFn
        Unit.__init__(self)

    def _getWordAddrStep(self):
        raise NotImplementedError("Should be overridden in concrete implementation, this is abstract class")

    def _getAddrStep(self):
        raise NotImplementedError("Should be overridden in concrete implementation, this is abstract class")

    def _config(self):
        self._intfCls._config(self)

    def _declr(self):
        addClkRstn(self)

        with self._paramsShared():
            self.bus = self._intfCls()

        self.decoded = StructIntf(self.STRUCT_TEMPLATE, instantiateFieldFn=self._mkFieldInterface)

    def getPort(self, transTmpl):
        o = transTmpl.origin
        return self.decoded._fieldsToInterfaces[o]

    def isInMyAddrRange(self, addrSig):
        return (addrSig >= self._getMinAddr()) & (addrSig < self._getMaxAddr())

    def walkFieldsAndIntf(self, transTmpl, structIntf):
        fieldTrans = transTmpl.walkFlatten(shouldEnterFn=self.shouldEnterFn)

        def shouldEnterIntf(intf):
            """
            :return: tuple (shouldEnter, shouldYield)
            """
            if isinstance(intf, InterfaceProxy) and intf._itemsInOne == 1:
                if isinstance(intf._origIntf, (RegCntrl, BramPort_withoutClk)):
                    return (False, True)
                else:
                    return (True, False)
            if isinstance(intf, (RegCntrl, BramPort_withoutClk)):
                if intf._widthMultiplier is not None:
                    return (False, False)
                else:
                    return (False, True)
            else:
                return (True, False)

        intfs = walkFlatten(structIntf, shouldEnterIntf)

        for (((base, end), transTmpl), intf) in zip(fieldTrans, intfs):
            if isinstance(intf, InterfaceProxy):
                _tTmpl = copy(transTmpl)
                _tTmpl.bitAddr = base
                _tTmpl.bitAddrEnd = end
                _tTmpl.origin = PartialField(transTmpl.origin)
                transTmpl = _tTmpl

            yield transTmpl, intf

    def _parseTemplate(self):
        self._directlyMapped = []
        self._bramPortMapped = []
        self.ADRESS_MAP = []

        self.WORD_ADDR_STEP = self._getWordAddrStep()
        self.ADDR_STEP = self._getAddrStep()

        AW = int(self.ADDR_WIDTH)
        SUGGESTED_AW = self._suggestedAddrWidth()
        assert SUGGESTED_AW <= AW, (SUGGESTED_AW, AW)
        tmpl = TransTmpl(self.STRUCT_TEMPLATE)

        for transTmpl, intf in self.walkFieldsAndIntf(tmpl, self.decoded):
            if isinstance(intf, InterfaceProxy):
                self.decoded._fieldsToInterfaces[transTmpl.origin] = intf
                intfClass = intf._origIntf.__class__
            else:
                intfClass = intf.__class__

            if issubclass(intfClass, RegCntrl):
                self._directlyMapped.append(transTmpl)

            elif issubclass(intfClass, BramPort_withoutClk):
                self._bramPortMapped.append(transTmpl)
            else:
                raise NotImplementedError(intf)

            self.ADRESS_MAP.append(transTmpl)

    def _getMaxAddr(self):
        """"
        Get maximum address value for this endpoint
        """
        lastItem = self.ADRESS_MAP[-1]
        return lastItem.bitAddrEnd // self._getAddrStep()

    def _getMinAddr(self):
        """"
        Get minimum address value for this endpoint
        """
        return self.ADRESS_MAP[0].bitAddr // self._getAddrStep()

    def _suggestedAddrWidth(self):
        """
        Based on strut template resolve how many bits for
        address is needed
        """
        bitSize = self.STRUCT_TEMPLATE.bit_length()
        wordAddrStep = self._getWordAddrStep()
        addrStep = self._getAddrStep()

        maxAddr = (bitSize // addrStep)

        # align to word size
        if maxAddr % wordAddrStep != 0:
            wordAddrStep += wordAddrStep - (maxAddr % wordAddrStep)

        return maxAddr.bit_length()
{'fraction_non_alphanumeric': 0.0956410438739956, 'fraction_numerical': 0.0012088459077010596, 'mean_word_length': 1.9802924348378894, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 16, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3688216', 'n_tokens_mistral': 4115, 'n_tokens_neox': 3865, 'n_words': 898}