hwt/hdl/ifContainter.py
def _cut_off_drivers_of(self, sig: RtlSignalBase):
        """
        Doc on parent class :meth:`HdlStatement._cut_off_drivers_of`
        """
        if len(self._outputs) == 1 and sig in self._outputs:
            self.parentStm = None
            return self

        # try to cut off all statements which are drivers of specified signal
        # in all branches
        child_keep_mask = []

        newIfTrue = []
        all_cut_off = True
        all_cut_off &= self._cut_off_drivers_of_list(
            sig, self.ifTrue, child_keep_mask, newIfTrue)
        self.ifTrue = list(compress(self.ifTrue, child_keep_mask))

        newElifs = []
        anyElifHit = False
        for cond, stms in self.elIfs:
            newCase = []
            child_keep_mask.clear()
            all_cut_off &= self._cut_off_drivers_of_list(
                sig, stms, child_keep_mask, newCase)

            _stms = list(compress(stms, child_keep_mask))
            stms.clear()
            stms.extend(_stms)

            if newCase:
                anyElifHit = True
            newElifs.append((cond, newCase))

        newIfFalse = None
        if self.ifFalse:
            newIfFalse = []
            child_keep_mask.clear()
            all_cut_off &= self._cut_off_drivers_of_list(
                sig, self.ifFalse, child_keep_mask, newIfFalse)
            self.ifFalse = list(compress(self.ifFalse, child_keep_mask))

        assert not all_cut_off, "everything was cut of but this should be already known at start"

        if newIfTrue or newIfFalse or anyElifHit or newIfFalse:
            # parts were cut off
            # generate new statement for them
            cond_sig = self.cond
            n = self.__class__(cond_sig, newIfTrue)
            for c, stms in newElifs:
                assert len(c) == 1
                c_sig = c[0]
                n.Elif(c_sig, stms)
            if newIfFalse is not None:
                n.Else(newIfFalse)

            if self.parentStm is None:
                ctx = n._get_rtl_context()
                ctx.statements.add(n)

            # update io of this
            self._inputs.clear()
            self._inputs.append(cond_sig)
            for c, _ in self.elIfs:
                self._inputs.extend(c)

            self._inputs.append(cond_sig)
            self._outputs.clear()

            out_add = self._outputs.append
            in_add = self._inputs.append

            for stm in self._iter_stms():
                for inp in stm._inputs:
                    in_add(inp)

                for outp in stm._outputs:
                    out_add(outp)

            if self._sensitivity is not None or self._enclosed_for is not None:
                raise NotImplementedError(
                    "Sensitivity and enclosure has to be cleaned first")

            return n
def _cut_off_drivers_of(self, sig: RtlSignalBase):
        """
        Doc on parent class :meth:`HdlStatement._cut_off_drivers_of`
        """
        if len(self._outputs) == 1 and sig in self._outputs:
            self.parentStm = None
            return self

        # try to cut off all statements which are drivers of specified signal
        # in all branches
        child_keep_mask = []

        newIfTrue = []
        all_cut_off = True
        all_cut_off &= self._cut_off_drivers_of_list(
            sig, self.ifTrue, child_keep_mask, newIfTrue)
        self.ifTrue = list(compress(self.ifTrue, child_keep_mask))

        newElifs = []
        anyElifHit = False
        for cond, stms in self.elIfs:
            newCase = []
            child_keep_mask.clear()
            all_cut_off &= self._cut_off_drivers_of_list(
                sig, stms, child_keep_mask, newCase)

            _stms = list(compress(stms, child_keep_mask))
            stms.clear()
            stms.extend(_stms)

            if newCase:
                anyElifHit = True
            newElifs.append((cond, newCase))

        newIfFalse = None
        if self.ifFalse:
            newIfFalse = []
            child_keep_mask.clear()
            all_cut_off &= self._cut_off_drivers_of_list(
                sig, self.ifFalse, child_keep_mask, newIfFalse)
            self.ifFalse = list(compress(self.ifFalse, child_keep_mask))

        assert not all_cut_off, "everything was cut of but this should be already known at start"

        if newIfTrue or newIfFalse or anyElifHit or newIfFalse:
            # parts were cut off
            # generate new statement for them
            cond_sig = self.cond
            n = self.__class__(cond_sig, newIfTrue)
            for c, stms in newElifs:
                assert len(c) == 1
                c_sig = c[0]
                n.Elif(c_sig, stms)
            if newIfFalse is not None:
                n.Else(newIfFalse)

            if self.parentStm is None:
                ctx = n._get_rtl_context()
                ctx.statements.add(n)

            # update io of this
            self._inputs.clear()
            self._inputs.append(cond_sig)
            for c, _ in self.elIfs:
                self._inputs.extend(c)

            self._inputs.append(cond_sig)
            self._outputs.clear()

            out_add = self._outputs.append
            in_add = self._inputs.append

            for stm in self._iter_stms():
                for inp in stm._inputs:
                    in_add(inp)

                for outp in stm._outputs:
                    out_add(outp)

            if self._sensitivity is not None or self._enclosed_for is not None:
                raise NotImplementedError(
                    "Sensitivity and enclosure has to be cleaned first")

            return n
Doc on parent class :meth:`HdlStatement._cut_off_drivers_of`