def removeUnconnectedSignals(netlist: "RtlNetlist"): """ Remove signal if does not affect output :attention: does not remove signals in cycles which does not affect outputs """ toSearch = [s for s, d in netlist.interfaces.items() if d != DIRECTION.IN] seen = set(toSearch) for c in netlist.subUnits: toSearch.extend(sig._sig for sig in walkPhysInterfaces(c)) while toSearch: _toSearch = [] for sig in toSearch: for e in sig.drivers: if isinstance(e, Operator): inputs = e.operands elif isinstance(e, HdlPortItem): # we are already added inputs of all components continue else: inputs = walkInputsForSpecificOutput(sig, e) for i in inputs: if isinstance(i, RtlSignalBase) and i not in seen: seen.add(i) _toSearch.append(i) nv = sig._nop_val if isinstance(nv, RtlSignalBase): if nv not in seen: seen.add(nv) _toSearch.append(nv) toSearch = _toSearch seen.update( [s for s, d in netlist.interfaces.items() if d == DIRECTION.IN]) for c in netlist.subUnits: seen.update(sig._sig for sig in walkPhysInterfaces(c)) for sig in netlist.signals: if sig in seen: continue for e in tuple(sig.drivers): # drivers of this signal are useless rm them if isinstance(e, Operator): removed_e = e elif isinstance(e, HdlPortItem): raise NotImplementedError(sig) else: removed_e = e._cut_off_drivers_of(sig) if removed_e is not None: # must not destroy before procesing inputs removed_e._destroy() netlist.signals = seen
def reconectArrayIntfSignalsToModel(parent, item): index = parent._arrayElemCache.index(item) for p, i in zip(walkPhysInterfaces(parent), walkPhysInterfaces(item)): s = i._sigInside width = s._dtype.bit_length() if s._dtype == BIT: lowerIndex = None upperIndex = (width * index) else: lowerIndex = (width * index) upperIndex = (width * (index + 1)) i._sigInside = IndexSimSignalProxy(i._name, p._sigInside, simBitsT(width, s._dtype.signed), upperIndex, lowerIndex)
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)
def _boundInterfacesToEntity(self, interfaces): externSignals = [] inftToPortDict = {} for p in self._entity.ports: inftToPortDict[p._interface] = p for intf in self._interfaces: if intf._isExtern: for s in walkPhysInterfaces(intf): externSignals.append(s) assert len(externSignals) == len(inftToPortDict.keys()) for s in externSignals: self._boundIntfSignalToEntity(s, inftToPortDict)
def beforeSim(self, simulator, synthesisedUnit): """ This method is called before first step of simulation. """ top = self.top self.tbEnt, self.tbArch, self.tbCtx = makeTestbenchTemplate(top) def reg(sigIntf): """register interface and create diver process for it""" proc = mkDriverProc(sigIntf, self.tbCtx) self.registered[sigIntf._sigInside] = proc self.tbArch.processes.append(proc) for s in walkPhysInterfaces(top): if s._direction is INTF_DIRECTION.SLAVE\ and isinstance(s._dtype, self.supported_type_classes): reg(s)
def connectUnpacked(src, dst, exclude=[]): """src is packed and it is unpacked and connected to dst""" # [TODO] parametrized offsets offset = 0 connections = [] for i in reversed(list(walkPhysInterfaces(dst))): if i in exclude: continue sig = i._sig t = sig._dtype if t == BIT: s = src[hInt(offset)] offset += 1 else: w = getWidthExpr(t) s = src[(w + offset):offset] offset += t.bit_length() connections.append(sig**s) return connections
def _tryExtractMultiplicationFactor(self): widths = [] # collect all widths for i in walkPhysInterfaces(self): if i._dtypeMatch or i._boundedEntityPort._dtype.constrain is None: # if is not constrained vector or type was resolved this can not be a interfaceArray return w = getWidthExpr(i._boundedEntityPort._dtype) widths.append(w) # find what have all widths in common splitedWidths = map(splitToTermSet, widths) arrLen = None for w in splitedWidths: if arrLen is None: arrLen = w else: arrLen = arrLen.intersection(w) if len(arrLen) == 1: # if is possible to determine arrLen return list(arrLen)[0]
def _Unit_makePublicIntfPrivateInImpl(self, intf): parent_u = intf._parent while not isinstance(parent_u, Unit): parent_u = parent_u._parent parent_u._interfaces.remove(intf) parent_u._private_interfaces.append(intf) for s in walkPhysInterfaces(intf): if s._direction == INTF_DIRECTION.SLAVE: ep = s._sig.endpoints ep.remove(s._hdl_port) elif s._direction == INTF_DIRECTION.MASTER: dr = s._sig.drivers dr.remove(s._hdl_port) else: raise ValueError(s._direction) s._sig.ctx.interfaces.pop(s._sig) self.parent._ctx.ent.ports.remove(s._hdl_port) s._hdl_port = None s._isExtern = False
def get_data(self, intf): rd = self.get_ready_signal(intf) vld = self.get_valid_signal(intf) return [x for x in walkPhysInterfaces(intf) if (x is not rd) and (x is not vld)]