def _toRtl(self, targetPlatform): assert not self._wasSynthetised() self._targetPlatform = targetPlatform if not hasattr(self, "_name"): self._name = self._getDefaultName() self._loadMyImplementations() # construct params for entity (generics) self._ctx.params = self._buildParams() externInterf = [] # prepare connections for i in self._interfaces: signals = i._signalsForInterface(self._ctx) if not i._isExtern: raise IntfLvlConfErr( "All interfaces in EmptyUnit has to be extern, %s: %s is not" % (self.__class__.__name__, i._getFullName())) externInterf.extend(signals) # i._resolveDirections() # connect outputs to dummy value for s in signals: if s._interface._direction == INTF_DIRECTION.SLAVE: s(s._dtype.fromPy(self._defVal)) if not externInterf: raise IntfLvlConfErr( "Can not find any external interface for unit %s" "- unit without interfaces are not allowed" % self._name) yield from self._synthetiseContext(externInterf)
def _connectToIter(self, master, exclude=None, fit=False): # [todo] implementatino for RtlSignals of HStruct type if exclude and (self in exclude or master in exclude): return if self._interfaces: for ifc in self._interfaces: if exclude and ifc in exclude: continue mIfc = getattr(master, ifc._name) if exclude and mIfc in exclude: continue if mIfc._masterDir == DIRECTION.OUT: if ifc._masterDir != mIfc._masterDir: raise IntfLvlConfErr("Invalid connection", ifc, "<=", mIfc) yield from ifc._connectTo(mIfc, exclude=exclude, fit=fit) else: if ifc._masterDir != mIfc._masterDir: raise IntfLvlConfErr("Invalid connection", mIfc, "<=", ifc) yield from mIfc._connectTo(ifc, exclude=exclude, fit=fit) else: dstSig = toHVal(self) srcSig = toHVal(master) if fit: srcSig = fitTo(srcSig, dstSig) yield dstSig(srcSig)
def _connectToIter(self, master, exclude, fit): # [todo] implementation for RtlSignals of HStruct type if exclude and (self in exclude or master in exclude): return if self._interfaces: seen_master_intfs = [] for ifc in self._interfaces: if exclude and ifc in exclude: mIfc = getattr(master, ifc._name, None) if mIfc is not None: seen_master_intfs.append(mIfc) continue mIfc = getattr(master, ifc._name) seen_master_intfs.append(mIfc) if exclude and mIfc in exclude: continue if mIfc._masterDir == DIRECTION.OUT: if ifc._masterDir != mIfc._masterDir: raise IntfLvlConfErr("Invalid connection", ifc, "<=", mIfc) yield from ifc._connectToIter(mIfc, exclude, fit) else: if ifc._masterDir != mIfc._masterDir: raise IntfLvlConfErr("Invalid connection", mIfc, "<=", ifc) yield from mIfc._connectToIter(ifc, exclude, fit) if len(seen_master_intfs) != len(master._interfaces): if exclude: # there is a possiblity that the master interface was excluded, # but we did not see it as the interface of the same name was not present on self for ifc in self._interfaces: if ifc in exclude or ifc not in seen_master_intfs: continue else: # ifc is an interface which is extra on master and is missing an equivalent on slave raise InterfaceStructureErr(self, master, exclude) else: raise InterfaceStructureErr(self, master, exclude) else: if master._interfaces: raise InterfaceStructureErr(self, master, exclude) dstSig = toHVal(self) srcSig = toHVal(master) if fit: srcSig = fitTo(srcSig, dstSig) yield dstSig(srcSig)
def _checkArchCompInstances(self): cInstances = len(self._architecture.componentInstances) units = len(self._units) if cInstances != units: inRtl = set(map(lambda x: x.name, self._architecture.componentInstances)) inIntf = set(map(lambda x: x._name + "_inst", self._units)) if cInstances > units: raise IntfLvlConfErr("_toRtl unit(s) %s were found in rtl but were not registered at %s" % (str(inRtl - inIntf), self._name)) elif cInstances < units: raise IntfLvlConfErr("_toRtl of %s: unit(s) %s were lost" % (self._name, str(inIntf - inRtl)))
def _connectToIter(self, master, masterIndex=None, slaveIndex=None, exclude=None, fit=False): if exclude and (self in exclude or master in exclude): return if self._interfaces: for ifc in self._interfaces: if exclude and ifc in exclude: continue mIfc = getattr(master, ifc._name) if exclude and mIfc in exclude: continue if mIfc._masterDir == DIRECTION.OUT: if ifc._masterDir != mIfc._masterDir: raise IntfLvlConfErr("Invalid connection %s <= %s" % (repr(ifc), repr(mIfc))) yield from ifc._connectTo(mIfc, masterIndex=masterIndex, slaveIndex=slaveIndex, exclude=exclude, fit=fit) else: if ifc._masterDir != mIfc._masterDir: raise IntfLvlConfErr("Invalid connection %s <= %s" % (repr(mIfc), repr(ifc))) yield from mIfc._connectTo(ifc, masterIndex=slaveIndex, slaveIndex=masterIndex, exclude=exclude, fit=fit) else: dstSig = toHVal(self) srcSig = toHVal(master) if masterIndex is not None: srcSig = aplyIndexOnSignal(srcSig, dstSig._dtype, masterIndex) if slaveIndex is not None: dstSig = aplyIndexOnSignal(dstSig, srcSig._dtype, slaveIndex) if fit: srcSig = fitTo(srcSig, dstSig) yield dstSig.__pow__(srcSig)
def nameAvailabilityCheck(obj, propName, prop): """ Check if not redefining property on obj """ if getattr(obj, propName, None) is not None: p = getattr(obj, propName) raise IntfLvlConfErr(f"{obj} already has property {propName:s} old:{p} new:{prop}")
def nameAvailabilityCheck(obj, propName, prop): """ Check if not redefining property on obj """ if getattr(obj, propName, None) is not None: raise IntfLvlConfErr("Already has parameter %s old:%s new:%s" % (propName, repr(getattr(obj, propName)), prop))
def _toRtl(self): assert not self._wasSynthetised() if not hasattr(self, "_name"): self._name = self._getDefaultName() for i in self._interfaces: i._setDirectionsLikeIn(INTF_DIRECTION.MASTER) self._loadMyImplementations() # construct globals (generics for entity) self._cntx.globals = self._globalsFromParams() externInterf = [] # prepare connections for i in self._interfaces: signals = i._signalsForInterface(self._cntx) if not i._isExtern: raise IntfLvlConfErr("All interfaces in EmptyUnit has to be extern, %s: %s is not" % (self.__class__.__name__, i._getFullName())) externInterf.extend(signals) # i._resolveDirections() # connect outputs to dummy value for s in signals: if s._interface._direction == INTF_DIRECTION.SLAVE: s ** s._dtype.fromPy(self._defaultValue) if not externInterf: raise Exception("Can not find any external interface for unit " + self._name \ + "- there is no such a thing as unit without interfaces") yield from self._synthetiseContext(externInterf)
def addP(n, p): p.name = n if n in params: raise IntfLvlConfErr( "Redefinition of generic '%s' while synthesis" " old:%r, new:%r" % (n, params[n], p)) params[n] = p
def getClk(unit): try: return unit.clk except AttributeError: pass raise IntfLvlConfErr("Can not find clock on unit %r" % (unit, ))
def addP(n: str, p: Param): if n in params: raise IntfLvlConfErr( "Redefinition of generic/param '%s' while synthesis" " old:%r, new:%r" % (n, params[n], p)) p.hdl_name = n params[n] = p
def Unit_checkCompInstances(u: Unit): cInstances = [o for o in u._ctx.arch.objs if isinstance(o, HdlCompInst)] cInst_cnt = len(cInstances) unit_cnt = len(u._units) if cInst_cnt != unit_cnt: inRtl = set(x.name for x in cInstances) inIntf = set(x._name for x in u._units) if cInst_cnt > unit_cnt: raise IntfLvlConfErr( "%s, %s: unit(s) were found in HDL but were" " not registered %s" % (u.__class__.__name__, u._name, u._getstr(inRtl - inIntf))) elif cInst_cnt < unit_cnt: raise IntfLvlConfErr( "%s, %s: _to_rtl: unit(s) are missing in produced HDL %s" % (u._name, u.__class__.__name__, str(inIntf - inRtl)))
def addP(n, p): # [TODO] case sensitivity based on active HDL p.name = n.upper() n = n.lower() if n in globalNames: raise IntfLvlConfErr("Redefinition of generic '%s' while synthesis old:%s, new:%s" % (n, repr(globalNames[n]), repr(p))) globalNames[n] = p
def _reverseDirection(self): """Reverse direction of this interface in implementation stage""" if self._dirLocked: raise IntfLvlConfErr( "Can not reverse direction on interface %s because it was locked (%s)" % (repr(self), self._direction)) self._direction = INTF_DIRECTION.opposite(self._direction) for intf in self._interfaces: intf._reverseDirection()
def getClk(unit: UnitBase): """ Get clock signal from unit instance """ try: return unit.clk except AttributeError: pass raise IntfLvlConfErr("Can not find clock signal on unit %r" % (unit, ))
def _checkCompInstances(self): cInstances = [o for o in self._ctx.arch.objs if isinstance(o, HdlCompInst)] cInst_cnt = len(cInstances) unit_cnt = len(self._units) if cInst_cnt != unit_cnt: # resolve the error message inRtl = set(x.name for x in cInstances) inIntf = set(x._name for x in self._units) cls_name = self.__class__.__name__ if cInst_cnt > unit_cnt: diff = inRtl - inIntf raise IntfLvlConfErr( f"{cls_name:s}, {self._name:s}: unit(s) were found in HDL but were" f" not registered {diff}") else: assert cInst_cnt < unit_cnt diff = inIntf - inRtl raise IntfLvlConfErr( f"{cls_name:s}, {self._name:s}: _to_rtl: unit(s) are missing in produced HDL {diff}")
def _checkCompInstances(self): cInstances = [ o for o in self._ctx.arch.objs if isinstance(o, HdlCompInst) ] cInst_cnt = len(cInstances) unit_cnt = len(self._units) if cInst_cnt != unit_cnt: # resolve the error message inRtl = set(x.name for x in cInstances) inIntf = set(x._name for x in self._units) if cInst_cnt > unit_cnt: raise IntfLvlConfErr( "%s, %s: unit(s) were found in HDL but were" " not registered %s" % (self.__class__.__name__, self._name, self._getstr(inRtl - inIntf))) else: assert cInst_cnt < unit_cnt raise IntfLvlConfErr( "%s, %s: _to_rtl: unit(s) are missing in produced HDL %s" % (self._name, self.__class__.__name__, str(inIntf - inRtl)))
def getRst(unit): try: return unit.rst except AttributeError: pass try: return unit.rst_n except AttributeError: pass raise IntfLvlConfErr("Can not find clock on unit %r" % (unit, ))
def _boundIntfSignalToEntity(self, interface, inftToPortDict): portItem = single(self._entity.ports, lambda x : x._interface == interface) interface._boundedEntityPort = portItem d = INTF_DIRECTION.asDirection(interface._direction) if d == DIRECTION.INOUT: portItem.direction = DIRECTION.INOUT if portItem.direction != d: # print(self._entity) # print(self._architecture) raise IntfLvlConfErr("Unit %s: Port %s does not have direction defined by interface %s, is %s should be %s" % (self._name, portItem.name, repr(interface), portItem.direction, d))
def _toRtl(self, targetPlatform: DummyPlatform): """ synthesize all subunits, make connections between them, build entity and component for this unit """ assert not self._wasSynthetised() self._targetPlatform = targetPlatform if not hasattr(self, "_name"): self._name = self._getDefaultName() for proc in targetPlatform.beforeToRtl: proc(self) self._ctx.params = self._buildParams() self._externInterf = [] # prepare subunits for u in self._units: yield from u._toRtl(targetPlatform) for u in self._units: subUnitName = u._name u._signalsForMyEntity(self._ctx, "sig_" + subUnitName) # prepare signals for interfaces for i in self._interfaces: signals = i._signalsForInterface(self._ctx) if i._isExtern: self._externInterf.extend(signals) for proc in targetPlatform.beforeToRtlImpl: proc(self) self._loadMyImplementations() yield from self._lazyLoaded if not self._externInterf: raise IntfLvlConfErr( "Can not find any external interface for unit %s" "- unit without interfaces are not allowed" % self._name) for proc in targetPlatform.afterToRtlImpl: proc(self) yield from self._synthetiseContext(self._externInterf) self._checkArchCompInstances() for proc in targetPlatform.afterToRtl: proc(self)
def getRst(unit: UnitBase): """ Get reset signal from unit instance """ try: return unit.rst except AttributeError: pass try: return unit.rst_n except AttributeError: pass raise IntfLvlConfErr("Can not find reset signal on unit %r" % (unit, ))
def __init__(self, cond, *statements): """ :param cond: condition in if statement :param statements: list of statements which should be active if condition is met """ cond_sig = _intfToSig(cond) if not isinstance(cond_sig, RtlSignalBase): raise IntfLvlConfErr("Condition is not signal, it is not certain" " if this is an error or desire ", cond_sig) super(If, self).__init__(cond_sig) self.rank = 1 self._inputs.append(cond_sig) cond_sig.endpoints.append(self) ev_dep = arr_any(discoverEventDependency(cond_sig), lambda x: True) self._event_dependent_from_branch = 0 if ev_dep else None self._register_stements(statements, self.ifTrue) self._get_rtl_context().statements.add(self)
def _resolveDirections(self, updateDir=True): allM, allS = self.__directionProbe() if allM and allS and self._arrayElemCache: # if direction is nod clear from this intf. and it has elems. allM, allS = self._arrayElemCache[0].__directionProbe() if allM and allS: self._direction = INTF_DIRECTION.UNKNOWN elif allM: self._direction = INTF_DIRECTION.MASTER elif allS: self._direction = INTF_DIRECTION.SLAVE else: raise IntfLvlConfErr( "Subinterfaces on %s \nhave not consistent directions\n%s" % (repr(self), '\n'.join( [str((i._direction, repr(i))) for i in self._interfaces]))) if updateDir: if self._direction == INTF_DIRECTION.UNKNOWN: self._direction = INTF_DIRECTION.MASTER self._setDirectionsLikeIn(self._direction)
def _to_rtl(self, target_platform: DummyPlatform, store_manager: "StoreManager"): """ synthesize all subunits, make connections between them, build entity and component for this unit """ if self._hdl_module_name is None: self._hdl_module_name = self._getDefaultName() if self._name is None: self._name = self._getDefaultName() self._target_platform = target_platform self._store_manager = store_manager do_serialize_this, replacement = store_manager.filter.do_serialize( self) if replacement is not None: assert not do_serialize_this assert len(self._interfaces) == len(replacement._interfaces), \ "No lazy loaded interfaces declared in _impl()" copy_HdlModuleDec(replacement, self) yield False, self self._cleanAsSubunit() self._units = None self._private_interfaces = None intf_map_repl_to_self = shared_comp_build_interface_map( replacement, self) intf_map_self_to_repl = { v: k for k, v in intf_map_repl_to_self.items() } self._shared_component_with = replacement, \ intf_map_self_to_repl, intf_map_repl_to_self return for proc in target_platform.beforeToRtl: proc(self) mdec = self._ctx.create_HdlModuleDec(self._hdl_module_name, store_manager, self._params) mdec.origin = self mdec.doc = self._get_hdl_doc() # prepare signals for interfaces for i in self._interfaces: if i._isExtern: ei = self._ctx.interfaces else: ei = None # we are reversing direction because we are looking # at the interface from inside of component i._signalsForInterface(self._ctx, ei, store_manager.name_scope, reverse_dir=True) store_manager.hierarchy_pop(mdec) if do_serialize_this: # prepare subunits for u in self._units: yield from u._to_rtl(target_platform, store_manager) # now every sub unit has a HdlModuleDec prepared for u in self._units: subUnitName = u._name u._signalsForSubUnitEntity(self._ctx, "sig_" + subUnitName) for proc in target_platform.beforeToRtlImpl: proc(self) try: store_manager.hierarchy_push(mdec) if do_serialize_this: self._loadImpl() yield from self._lazy_loaded if not self._ctx.interfaces: raise IntfLvlConfErr( "Can not find any external interface for unit %s" "- unit without interfaces are not synthetisable" % self._name) for proc in target_platform.afterToRtlImpl: proc(self) mdec.params.sort(key=lambda x: x.name) mdec.ports.sort(key=lambda x: x.name) if do_serialize_this: # synthesize signal level context mdef = self._ctx.create_HdlModuleDef(target_platform, store_manager) mdef.origin = self for intf in self._interfaces: if intf._isExtern: # reverse because other components # looks at this interface from the outside intf._reverseDirection() if do_serialize_this: store_manager.write(mdef) yield True, self # after synthesis clean up interface so this :class:`hwt.synthesizer.unit.Unit` object can be # used elsewhere self._cleanAsSubunit() if do_serialize_this: self._checkCompInstances() for proc in target_platform.afterToRtl: proc(self) finally: store_manager.hierarchy_pop(mdec)
def __getitem__(self, key): if self._multipliedBy is None: raise IntfLvlConfErr( "interface %s is not array and can not be indexe on" % self._name) return self._arrayElemCache[key]