예제 #1
0
파일: statements.py 프로젝트: mgielda/hwt
    def HWProcess(cls, proc, ctx):
        """
        Serialize HWProcess objects
        """
        body = proc.statements
        extraVars = []
        extraVarsSerialized = []

        hasToBeVhdlProcess = extraVars or\
            arr_any(body,
                    lambda x: isinstance(x,
                                         (IfContainer,
                                          SwitchContainer,
                                          WhileContainer,
                                          WaitStm)) or
                    (isinstance(x, Assignment) and
                     x.indexes))

        anyIsEventDependnt = arr_any(
            proc.sensitivityList, lambda s: isinstance(s, Operator))
        sensitivityList = sorted(
            map(lambda s: cls.sensitivityListItem(s, ctx,
                                                  anyIsEventDependnt),
                proc.sensitivityList))

        if hasToBeVhdlProcess:
            childCtx = ctx.withIndent()
        else:
            childCtx = ctx

        def createTmpVarFn(suggestedName, dtype):
            # [TODO] it is better to use RtlSignal
            s = SignalItem(None, dtype, virtualOnly=True)
            s.name = childCtx.scope.checkedName(suggestedName, s)
            s.hidden = False
            serializedS = cls.SignalItem(s, childCtx, declaration=True)
            extraVars.append(s)
            extraVarsSerialized.append(serializedS)
            return s

        childCtx.createTmpVarFn = createTmpVarFn

        statemets = [cls.asHdl(s, childCtx) for s in body]

        if hasToBeVhdlProcess:
            proc.name = ctx.scope.checkedName(proc.name, proc)

        extraVarsInit = []
        for s in extraVars:
            a = Assignment(s.defVal, s, virtualOnly=True)
            extraVarsInit.append(cls.Assignment(a, childCtx))

        return cls.processTmpl.render(
            indent=getIndent(ctx.indent),
            name=proc.name,
            hasToBeVhdlProcess=hasToBeVhdlProcess,
            extraVars=extraVarsSerialized,
            sensitivityList=" or ".join(sensitivityList),
            statements=extraVarsInit + statemets
        )
예제 #2
0
    def HWProcess(cls, proc: HWProcess, ctx):
        """
        Serialize HWProcess objects
        """
        body = proc.statements
        extraVars = []
        extraVarsSerialized = []

        anyIsEventDependnt = arr_any(
            proc.sensitivityList, lambda s: isinstance(s, Operator))
        sensitivityList = sorted(
            map(lambda s: cls.sensitivityListItem(s, ctx,
                                                  anyIsEventDependnt),
                proc.sensitivityList))

        hasToBeProcess = arr_any(
            proc.outputs,
            lambda x: verilogTypeOfSig(x) == SIGNAL_TYPE.REG
        )

        if hasToBeProcess:
            childCtx = ctx.withIndent()
        else:
            childCtx = ctx

        def createTmpVarFn(suggestedName, dtype):
            s = RtlSignal(None, None, dtype, virtual_only=True)
            s.name = childCtx.scope.checkedName(suggestedName, s)
            s.hidden = False
            serializedS = cls.SignalItem(s, childCtx, declaration=True)
            extraVars.append(s)
            extraVarsSerialized.append(serializedS)
            return s

        childCtx.createTmpVarFn = createTmpVarFn
        statemets = [cls.asHdl(s, childCtx) for s in body]

        if hasToBeProcess:
            proc.name = ctx.scope.checkedName(proc.name, proc)

        extraVarsInit = []
        for s in extraVars:
            a = Assignment(s.def_val, s, virtual_only=True)
            extraVarsInit.append(cls.Assignment(a, childCtx))

        return cls.processTmpl.render(
            indent=getIndent(ctx.indent),
            name=proc.name,
            hasToBeProcess=hasToBeProcess,
            extraVars=extraVarsSerialized,
            sensitivityList=" or ".join(sensitivityList),
            statements=extraVarsInit + statemets
        )
예제 #3
0
파일: utils.py 프로젝트: saislam/hwt
def systemCTypeOfSig(s):
    """
    Check if is register or wire
    """
    if isinstance(s, HdlIdDef):
        s = s.origin

    if isinstance(s, HdlPortItem):
        if s.direction == DIRECTION.IN or s.direction == DIRECTION.INOUT:
            return SIGNAL_TYPE.PORT_WIRE

        t = systemCTypeOfSig(s.getInternSig())
        if t == SIGNAL_TYPE.WIRE:
            return SIGNAL_TYPE.PORT_WIRE
        elif t == SIGNAL_TYPE.REG:
            return SIGNAL_TYPE.PORT_REG
        else:
            raise ValueError(t)
    elif isinstance(s, Param):
        return SIGNAL_TYPE.PORT_REG
    elif s._const or\
        arr_any(s.drivers,
                lambda d: isinstance(d, HdlStatement)
                and d._event_dependent_from_branch is not None):

        return SIGNAL_TYPE.REG
    else:
        return SIGNAL_TYPE.WIRE
예제 #4
0
    def __init__(self, switchOn):
        switchOn = _intfToSig(switchOn)
        if not isinstance(switchOn, RtlSignalBase):
            raise HwtSyntaxError("Select is not signal, it is not certain"
                                 " if this an error or desire")
        if arr_any(discoverEventDependency(switchOn), lambda x: True):
            raise HwtSyntaxError("Can not switch on result of event operator")

        super(Switch, self).__init__(switchOn, [])
        switchOn.ctx.statements.add(self)
예제 #5
0
def systemCTypeOfSig(signalItem):
    """
    Check if is register or wire
    """
    if signalItem._const or\
       arr_any(signalItem.drivers,
               lambda d: isinstance(d, HdlStatement)
               and d._now_is_event_dependent):

        return SIGNAL_TYPE.REG
    else:
        return SIGNAL_TYPE.WIRE
예제 #6
0
    def _connectMyElems(self):
        if self._arrayElemCache:
            for indx, e in enumerate(self._arrayElemCache):
                elemHasConnections = arr_any(
                    walkPhysInterfaces(e),
                    lambda x: bool(x._sig.endpoints) or bool(x._sig.drivers))
                if elemHasConnections:
                    e._resolveDirections()

                    if e._direction == INTF_DIRECTION.MASTER:
                        e._connectTo(self, masterIndex=indx)
                    else:
                        self._connectTo(e, slaveIndex=indx)
예제 #7
0
    def Elif(self, cond, *statements):
        cond = _intfToSig(cond)
        self.nowIsEventDependent = self.nowIsEventDependent or\
                                   arr_any(discoverEventDependency(cond), lambda x: True)
        thisCond = AndReducedContainer()
        thisCond.add(cond)
        for c in reversed(self.elifConds):
            thisCond.add(~c)
        thisCond.add(~self.cond)

        self._appendStatements(thisCond, statements)

        self.elifConds.append(cond)

        return self
예제 #8
0
파일: utils.py 프로젝트: mgielda/hwt
def verilogTypeOfSig(signalItem):
    """
    Check if is register or wire
    """
    driver_cnt = len(signalItem.drivers)
    if signalItem._const or driver_cnt > 1 or\
       arr_any(signalItem.drivers, _isEventDependentDriver):
        return SIGNAL_TYPE.REG
    else:
        if driver_cnt == 1:
            d = signalItem.drivers[0]
            if not isinstance(d, (Assignment, PortItem)):
                return SIGNAL_TYPE.REG

        return SIGNAL_TYPE.WIRE
예제 #9
0
    def HWProcess(cls, proc: HWProcess, ctx: SerializerCtx):
        body = proc.statements
        assert body
        proc.name = ctx.scope.checkedName(proc.name, proc)
        sensitivityList = sorted(
            map(cls.sensitivityListItem, proc.sensitivityList))

        childCtx = ctx.withIndent(2)
        _body = "\n".join([cls.stmAsHdl(stm, childCtx) for stm in body])

        return processTmpl.render(hasConditions=arr_any(
            body, lambda stm: not isinstance(stm, Assignment)),
                                  name=proc.name,
                                  sensitivityList=sensitivityList,
                                  stmLines=[_body])
예제 #10
0
    def Elif(self, cond, *statements):
        assert self.parentStm is None
        self.rank += 1
        cond_sig = _intfToSig(cond)

        self._now_is_event_dependent = arr_any(
            discoverEventDependency(cond_sig), lambda x: True)

        self._inputs.append(cond_sig)
        cond_sig.endpoints.append(self)

        case = []
        self.elIfs.append((cond_sig, case))
        self._register_stements(statements, case)

        return self
예제 #11
0
    def as_hdl_HdlStatementBlock(self,
                                 proc: HdlStatementBlock) -> iHdlStatement:
        """
        Serialize HdlStatementBlock objects as process if top statement
        """
        if isinstance(proc, ALL_STATEMENT_CLASSES):
            return proc
        assert proc.parentStm is None, proc
        body = proc.statements

        hasToBeVhdlProcess = self.has_to_be_process(proc)

        with WithNameScope(self, self.name_scope.level_push(proc.name)):
            tmpVars = self.TMP_VAR_CONSTRUCTOR(self, self.name_scope)
            with TmpVarsSwap(self, tmpVars):
                statements = [self.as_hdl(s) for s in body]

                hasToBeVhdlProcess |= bool(tmpVars.extraVarsHdl)

                if hasToBeVhdlProcess:
                    tmpVars.sort_hdl_declarations_first()
                    statements = tmpVars.extraVarsHdl + statements

                if self.can_pop_process_wrap(statements, hasToBeVhdlProcess):
                    return statements[0]
                else:
                    p = HdlStmProcess()
                    p.labels.append(proc.name)

                    if not statements:
                        pass  # no body
                    elif len(statements) == 1:
                        # body made of just a singe statement
                        p.body = statements[0]
                    else:
                        p.body = HdlStmBlock()
                        assert isinstance(statements, list)
                        p.body.body = statements
                    anyIsEventDependnt = arr_any(
                        proc._sensitivity, lambda s: isinstance(s, Operator))
                    p.sensitivity = sorted([
                        self.sensitivityListItem(s, anyIsEventDependnt)
                        for s in proc._sensitivity
                    ])
                    return p
예제 #12
0
    def HWProcess(cls, proc, scope):
        """
        Serialize HWProcess objects as VHDL

        :param scope: name scope to prevent name collisions
        """
        body = proc.statements
        extraVars = []
        extraVarsSerialized = []

        def createTmpVarFn(suggestedName, dtype):
            # [TODO] it is better to use RtlSignal
            s = SignalItem(None, dtype, virtualOnly=True)
            s.name = scope.checkedName(suggestedName, s)
            s.hidden = False
            serializedS = cls.SignalItem(s, createTmpVarFn, declaration=True)
            extraVars.append(s)
            extraVarsSerialized.append(serializedS)
            return s

        sensitivityList = sorted(
            map(lambda s: cls.sensitivityListItem(s, None),
                proc.sensitivityList))
        statemets = [cls.asHdl(s, createTmpVarFn) for s in body]

        hasToBeVhdlProcess = extraVars or arr_any(
            body, lambda x: isinstance(x, (IfContainer, SwitchContainer,
                                           WhileContainer, WaitStm)))

        if hasToBeVhdlProcess:
            proc.name = scope.checkedName(proc.name, proc)

        extraVarsInit = []
        for s in extraVars:
            a = Assignment(s.defaultVal, s, virtualOnly=True)
            extraVarsInit.append(cls.Assignment(a, createTmpVarFn))

        return processTmpl.render({
            "name": proc.name,
            "hasToBeVhdlProcess": hasToBeVhdlProcess,
            "extraVars": extraVarsSerialized,
            "sensitivityList": ", ".join(sensitivityList),
            "statements": extraVarsInit + statemets
        })
예제 #13
0
    def renderContent(self):
        """
        Walk from outputs to inputs
        for each public signal register port of wrap node if required
        lazy load all operator and statement nodes for signals
        """
        stm = self.stm
        portCtx = self.portCtx
        # for each inputs and outputs render expression trees

        # walk statements and render muxs and memories
        for o in stm._outputs:
            if not self.isVirtual:
                portCtx.register(o, PortType.OUTPUT)

        canHaveRamPorts = isinstance(stm, IfContainer) and arr_any(
            chain(stm._inputs, stm._outputs),
            lambda s: isinstance(s._dtype, HArray))
        # render RAM ports
        consumedOutputs = set()
        if canHaveRamPorts:
            for pType, memSig, addrSig, enSig, io in detectRamPorts(
                    stm, stm.cond):
                if pType == RAM_READ:
                    self.createRamReadNode(memSig, enSig, addrSig, io, True)
                    consumedOutputs.add(io)

                elif pType == RAM_WRITE:
                    self.createRamWriteNode(memSig, enSig, addrSig, io, None,
                                            True)
                    consumedOutputs.add(memSig)

                else:
                    raise TypeError()

        for o in stm._outputs:
            if o not in consumedOutputs:
                self.renderForSignal(stm, o, True)

        if not self.isVirtual:
            self.netCtxs.applyConnections(self.node)
예제 #14
0
파일: code.py 프로젝트: arnabd88/hwt
    def __init__(self, cond, *statements):
        """
        :param cond: condition in if statement
        :param statements: list of statements which should be active
            if condition is met
        """
        cond_sig = _intfToSig(cond)
        if not isinstance(cond_sig, RtlSignalBase):
            raise IntfLvlConfErr("Condition is not signal, it is not certain"
                                 " if this is an error or desire ", cond_sig)

        super(If, self).__init__(cond_sig)
        self.rank = 1
        self._inputs.append(cond_sig)
        cond_sig.endpoints.append(self)

        ev_dep = arr_any(discoverEventDependency(cond_sig), lambda x: True)
        self._event_dependent_from_branch = 0 if ev_dep else None

        self._register_stements(statements, self.ifTrue)
        self._get_rtl_context().statements.add(self)
예제 #15
0
파일: busEndpoint.py 프로젝트: Nic30/hwtLib
    def walkFieldsAndIntf(self, transTmpl, structIntf):
        intfIt = ObjIteratorCtx(structIntf)
        fieldTrans = transTmpl.walkFlatten(
            shouldEnterFn=self._shouldEnterForTransTmpl,
            otherObjItCtx=intfIt)

        hasAnyInterface = False
        for ((base, end), transTmpl) in fieldTrans:
            intf = intfIt.actual
            isPartOfSomeArray = arr_any(intfIt.onParentNames, lambda x: isinstance(x, int))
            if isPartOfSomeArray:
                _tTmpl = copy(transTmpl)
                _tTmpl.bitAddr = base
                _tTmpl.bitAddrEnd = end
                _tTmpl.origin = PartialField(transTmpl.origin)
                transTmpl = _tTmpl
                self.decoded._fieldsToInterfaces[transTmpl.origin] = intf

            yield transTmpl, intf
            hasAnyInterface = True

        assert hasAnyInterface
예제 #16
0
    def walkFieldsAndIntf(self, transTmpl, structIntf):
        intfIt = ObjIteratorCtx(structIntf)
        fieldTrans = transTmpl.walkFlatten(
            shouldEnterFn=self._shouldEnterForTransTmpl, otherObjItCtx=intfIt)

        hasAnyInterface = False
        for ((base, end), transTmpl) in fieldTrans:
            intf = intfIt.actual
            isPartOfSomeArray = arr_any(intfIt.onParentNames,
                                        lambda x: isinstance(x, int))
            if isPartOfSomeArray:
                _tTmpl = copy(transTmpl)
                _tTmpl.bitAddr = base
                _tTmpl.bitAddrEnd = end
                _tTmpl.origin = PartialField(transTmpl.origin)
                transTmpl = _tTmpl
                self.decoded._fieldsToInterfaces[transTmpl.origin] = intf

            yield transTmpl, intf
            hasAnyInterface = True

        assert hasAnyInterface
예제 #17
0
    def xml(self):
        # Vivado 2015.2 bug - order of all elements is NOT optional
        for prefix, uri in ns.items():
            etree.register_namespace(prefix, uri)
        c = mkSpiElm("component")
        appendStrElements(c, self, self._strValues[:-1])
        if arr_any(self.busInterfaces, lambda intf: hasattr(intf, "_bi")):
            bi = appendSpiElem(c, "busInterfaces")
            for intf in self.busInterfaces:  # for all interfaces which have bus interface class
                if hasattr(intf, "_bi"):
                    bi.append(intf._bi.asElem())

        c.append(self.model.asElem())
        self._xmlFileSets(c)

        appendStrElements(c, self, [self._strValues[-1]])
        self._xmlParameters(c)
        c.append(
            self.vendorExtensions.asElem(self.name + "_v" + self.version,
                                         revision=str(int(time()))))

        return c
예제 #18
0
    def as_hdl_HdlStatementBlock(self,
                                 proc: HdlStatementBlock) -> iHdlStatement:
        """
        Serialize HdlStatementBlock objects as process if top statement
        """
        if isinstance(proc, HdlStmProcess):
            return proc
        assert proc.parentStm is None, proc
        body = proc.statements
        extraVars = []
        extraVarsHdl = []

        hasToBeVhdlProcess = self.has_to_be_process(proc)

        def createTmpVarInCurrentBlock(suggestedName,
                                       dtype,
                                       const=False,
                                       def_val=None):
            # create a new tmp variable in current process
            s = RtlSignal(None, None, dtype, virtual_only=True)
            s.name = self.name_scope.checked_name(suggestedName, s)
            s.hidden = False
            s._const = const
            if def_val is not None:
                s.def_val = def_val
                s._set_def_val()

            as_hdl = self.as_hdl_SignalItem(s, declaration=True)
            extraVars.append(s)
            extraVarsHdl.append(as_hdl)
            return s

        with WithNameScope(self, self.name_scope.level_push(proc.name)):
            with CreateTmpVarFnSwap(self, createTmpVarInCurrentBlock):
                statements = [self.as_hdl(s) for s in body]

                # create a initializer for tmp variables
                # :note: we need to do this here because now it is sure that
                #     the drivers of tmp variable will not be modified
                extraVarsInit = self.as_hdl_extraVarsInit(extraVars)

                hasToBeVhdlProcess |= bool(extraVars)

                if hasToBeVhdlProcess:
                    statements = extraVarsHdl + extraVarsInit + statements
                if self.can_pop_process_wrap(statements, hasToBeVhdlProcess):
                    return statements[0]
                else:
                    p = HdlStmProcess()
                    p.labels.append(proc.name)

                    if not statements:
                        pass  # no body
                    elif len(statements) == 1:
                        # body made of just a singe statement
                        p.body = statements[0]
                    else:
                        p.body = HdlStmBlock()
                        assert isinstance(statements, list)
                        p.body.body = statements
                    anyIsEventDependnt = arr_any(
                        proc._sensitivity, lambda s: isinstance(s, Operator))
                    p.sensitivity = sorted([
                        self.sensitivityListItem(s, anyIsEventDependnt)
                        for s in proc._sensitivity
                    ])
                    return p
예제 #19
0
def typeIsParametrized(dtype):
    c = dtype.constrain
    if c is None:
        return False
    else:
        return arr_any(list(walkSignalsInExpr(c)), lambda x: True)
예제 #20
0
파일: statements.py 프로젝트: Ben-401/hwt
    def HWProcess(cls, proc, ctx):
        """
        Serialize HWProcess objects as VHDL

        :param scope: name scope to prevent name collisions
        """
        body = proc.statements
        extraVars = []
        extraVarsSerialized = []

        hasToBeVhdlProcess = arr_any(body,
                                     lambda x: isinstance(x,
                                                          (IfContainer,
                                                           SwitchContainer,
                                                           WhileContainer,
                                                           WaitStm)))

        sensitivityList = sorted(
            map(lambda s: cls.sensitivityListItem(s, ctx),
                proc.sensitivityList))

        if hasToBeVhdlProcess:
            childCtx = ctx.withIndent()
        else:
            childCtx = copy(ctx)

        def createTmpVarFn(suggestedName, dtype):
            s = RtlSignal(None, None, dtype, virtualOnly=True)
            s.name = ctx.scope.checkedName(suggestedName, s)
            s.hidden = False
            serializedS = cls.SignalItem(s, childCtx, declaration=True)
            extraVars.append(s)
            extraVarsSerialized.append(serializedS)
            return s

        childCtx.createTmpVarFn = createTmpVarFn

        statemets = [cls.asHdl(s, childCtx) for s in body]
        proc.name = ctx.scope.checkedName(proc.name, proc)

        extraVarsInit = []
        for s in extraVars:
            if isinstance(s.defVal, RtlSignalBase) or s.defVal.vldMask:
                a = Assignment(s.defVal, s, virtualOnly=True)
                extraVarsInit.append(cls.Assignment(a, childCtx))
            else:
                assert s.drivers, s
            for d in s.drivers:
                extraVarsInit.append(cls.asHdl(d, childCtx))

        _hasToBeVhdlProcess = hasToBeVhdlProcess
        hasToBeVhdlProcess = extraVars or hasToBeVhdlProcess

        if hasToBeVhdlProcess and not _hasToBeVhdlProcess:
            # add indent because we did not added it before because we did not
            # know t
            oneIndent = getIndent(1)
            statemets = list(map(lambda x: oneIndent + x, statemets))

        return cls.processTmpl.render(
            indent=getIndent(ctx.indent),
            name=proc.name,
            hasToBeVhdlProcess=hasToBeVhdlProcess,
            extraVars=extraVarsSerialized,
            sensitivityList=", ".join(sensitivityList),
            statements=extraVarsInit + statemets
        )