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)
def Else(self, *statements): assert self.parentStm is None if self.ifFalse is not None: raise HwtSyntaxError( "Else on this if-then-else statemen was aready used") self.rank += 1 self.ifFalse = [] self._register_stements(statements, self.ifFalse) return self
def registerInternSig(self, signal): """ Connect internal signal to port item, this connection is used by simulator and only output port items will be connected """ if self.direction == DIRECTION.OUT: if self.src is not None: raise HwtSyntaxError("Port %s is already associated with %s" % (self.name, str(self.src))) self.src = signal elif self.direction == DIRECTION.IN: if self.dst is not None: raise HwtSyntaxError("Port %s is already associated with %s" % (self.name, str(self.dst))) self.dst = signal else: raise NotImplementedError(self.direction)
def connectSig(self, signal): """ Connect to port item on subunit """ if self.direction == DIRECTION.IN: if self.src is not None: raise HwtSyntaxError("Port %s is already associated with %r" % (self.name, self.src)) self.src = signal signal.endpoints.append(self) elif self.direction == DIRECTION.OUT: if self.dst is not None: raise HwtSyntaxError("Port %s is already associated with %r" % (self.name, self.dst)) self.dst = signal signal.drivers.append(self) else: raise NotImplementedError(self) signal.hidden = False signal.ctx.subUnits.add(self.unit)
def _discover_sensitivity(self, seen) -> None: """ Doc on parent class :meth:`HdlStatement._discover_sensitivity` """ assert self._sensitivity is None, self ctx = self._sensitivity = SensitivityCtx() casual_sensitivity = set() self.switchOn._walk_sensitivity(casual_sensitivity, seen, ctx) if ctx.contains_ev_dependency: raise HwtSyntaxError("Can not switch on event operator result", self.switchOn) ctx.extend(casual_sensitivity) for stm in self._iter_stms(): stm._discover_sensitivity(seen) ctx.extend(stm._sensitivity)
def _statements_to_HWProcesses(_statements, tryToSolveCombLoops)\ -> Generator[HWProcess, None, None]: assert _statements # try to simplify statements proc_statements = [] for _stm in _statements: stms, _ = _stm._try_reduce() proc_statements.extend(stms) outputs = UniqList() _inputs = UniqList() sensitivity = UniqList() enclosed_for = set() for _stm in proc_statements: seen = set() _stm._discover_sensitivity(seen) _stm._discover_enclosure() outputs.extend(_stm._outputs) _inputs.extend(_stm._inputs) sensitivity.extend(_stm._sensitivity) enclosed_for.update(_stm._enclosed_for) enclosure_values = {} for sig in outputs: # inject nopVal if needed if sig._useNopVal: n = sig._nopVal enclosure_values[sig] = n if enclosure_values: do_enclose_for = list(where(outputs, lambda o: o in enclosure_values)) fill_stm_list_with_enclosure(None, enclosed_for, proc_statements, do_enclose_for, enclosure_values) if proc_statements: for o in outputs: assert not o.hidden, o seen = set() inputs = UniqList() for i in _inputs: inputs.extend(i._walk_public_drivers(seen)) intersect = outputs.intersection_set(sensitivity) if intersect: if not tryToSolveCombLoops: raise HwtSyntaxError( "Combinational loop on signal(s)", intersect) # try to solve combinational loops by separating drivers of signals # from statements for sig in intersect: proc_statements, proc_stms_select = cut_off_drivers_of( sig, proc_statements) yield from _statements_to_HWProcesses(proc_stms_select, False) if proc_statements: yield from _statements_to_HWProcesses(proc_statements, False) else: name = name_for_process(outputs) yield HWProcess("assig_process_" + name, proc_statements, sensitivity, inputs, outputs) else: assert not outputs # this can happen e.g. when If does not contains any Assignment pass