def _replace_child_statement(self, stm: HdlStatement, replacement: List[HdlStatement], update_io: bool) -> None: if update_io: raise NotImplementedError() for branch_list in (self.ifTrue, *(elif_stms for _, elif_stms in self.elIfs), self.ifFalse): if branch_list is None: continue try: i = branch_list.index(stm) except ValueError: # not in list continue self.rank -= stm.rank branch_list[i:i + 1] = replacement for rstm in replacement: rstm._set_parent_stm(self) # reset IO because it was shared with this statement stm._destroy() return raise ValueError("Statement", stm, "not found in ", self)
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