Example #1
0
def walk_assignments(stm: HdlStatement, dst: RtlSignal)\
        ->Generator[Assignment, None, None]:
    if isinstance(stm, Assignment):
        if dst is stm.dst:
            yield stm
    else:
        for _stm in stm._iter_stms():
            yield from walk_assignments(_stm, dst)
Example #2
0
def _count_mux_inputs_for_outputs(stm: HdlStatement, cnt):
    if isinstance(stm, Assignment):
        cnt[stm.dst] += 1
    else:
        for _stm in stm._iter_stms():
            if isinstance(_stm, Assignment):
                cnt[_stm.dst] += 1
            else:
                _count_mux_inputs_for_outputs(_stm, cnt)
Example #3
0
def walkInputsForSpecificOutput(output_sig: RtlSignalBase, stm: HdlStatement):
    if output_sig not in stm._outputs:
        return
    if isinstance(stm, Assignment):
        assert stm.dst is output_sig
        yield from stm._inputs
    elif isinstance(stm, IfContainer):
        yield stm.cond
        for c, _ in stm.elIfs:
            yield c
        for _stm in stm._iter_stms():
            yield from walkInputsForSpecificOutput(output_sig, _stm)
    elif isinstance(stm, SwitchContainer):
        yield stm.switchOn
        for _stm in stm._iter_stms():
            yield from walkInputsForSpecificOutput(output_sig, _stm)
    else:
        raise NotImplementedError(stm)
Example #4
0
def find_independent_slice_drivers(stm: HdlStatement):
    if isinstance(stm, Assignment):
        if stm.indexes and len(stm.indexes) == 1 and isinstance(
                stm.dst._dtype, Bits):
            dst = stm.dst
            for i in stm.indexes:
                if not isConst(i):
                    return

            can_directly_replace_with_src_expr = stm.parentStm is None
            yield (dst, tuple(stm.indexes), can_directly_replace_with_src_expr,
                   stm.src if can_directly_replace_with_src_expr else None)
    else:
        for _stm in stm._iter_stms():
            yield from find_independent_slice_drivers(_stm)
Example #5
0
def extract_part_drivers_stm(stm: HdlStatement,
                             signal_parts: Dict[RtlSignal,
                                                List[Tuple[RtlSignal,
                                                           List[HValue]]]]):
    if isinstance(stm, Assignment):
        if stm.indexes and len(stm.indexes) == 1:
            dst = stm.dst
            parts = signal_parts.get(dst, None)
            if parts is None:
                return False
            indexes = _format_indexes(stm.indexes)
            new_dsts, do_remove_stm = parts[indexes]
            if isinstance(new_dsts, list):
                assert len(new_dsts) > 1, (dst, new_dsts, stm)
                assert not do_remove_stm, (dst, new_dsts, stm)
                # the driven slice was split to multiple sub slices
                replacement = []
                dst_offset = new_dsts[0][-1][1]
                for i in new_dsts:
                    new_dst = parts[i][0]
                    new_src = stm.src
                    for _i in i:
                        high, low = _i[0] - dst_offset, _i[1] - dst_offset
                        assert high > 0 and low >= 0, dst_offset
                        assert high > low, (dst, stm, (high, low))
                        new_src = new_src[high:low]
                    a = new_dst(new_src)
                    replacement.append(a)

                # it has to hav parent statement because it needs to be nested
                # because otherwise it would not have some overlapping parts driven diferently
                # inder some condition
                stm.parentStm._replace_child_statement(stm, replacement, False)
            elif do_remove_stm:
                # remove current assignment because we are using src directly
                assert stm.parentStm is None, stm
                stm._destroy()
            else:
                # rewrite the Assignment instance to use new dst
                replacement = [
                    new_dsts(stm.src),
                ]
                stm.parentStm._replace_child_statement(stm, replacement, False)

            return True

    elif isinstance(stm, (IfContainer, SwitchContainer, HdlStatementBlock)):
        modified = False
        for _stm in stm._iter_stms():
            modified |= extract_part_drivers_stm(_stm, signal_parts)
        if modified:
            assert not stm._enclosed_for, "_enclosed_for is expected not to be initialized yet"
            outputs = stm._outputs
            inputs = stm._inputs
            stm._outputs = UniqList()
            stm._inputs = UniqList()
            stm._collect_io()
            if stm.parentStm is None:
                for o in outputs:
                    if o not in stm._outputs:
                        o.drivers.remove(stm)

                for i in inputs:
                    if i not in stm._inputs:
                        i.endpoints.remove(stm)

            return True

    else:
        raise NotImplementedError("Unknown statement ", stm)

    return False