def netlistToVhdlStr(name: str, netlist: RtlNetlist, interfaces: Dict[RtlSignal, DIRECTION]): name_scope = NameScope(None, name, True) buff = StringIO() store_manager = SaveToStream(Vhdl2008Serializer, buff) netlist.create_HdlModuleDec(name, store_manager, {}) netlist.interfaces = interfaces for s, d in interfaces.items(): s._interface = True pi = portItemfromSignal(s, netlist, d) # port of current top component s.name = name_scope.checked_name(s.name, s) pi.connectInternSig(s) netlist.ent.ports.append(pi) netlist.ent.ports.sort(key=lambda x: x.name) netlist.create_HdlModuleDef(DummyPlatform(), store_manager) store_manager.write(netlist.arch) return buff.getvalue()
class Unit(PropDeclrCollector, UnitImplHelpers): """ Container of the netlist with interfaces and internal hierarchical structure :cvar ~._serializeDecision: function to decide if HDL object derived from this unit should be serialized or not, if None all is always serialized :cvar ~._PROTECTED_NAMES: set of names which can not be overridden :ivar ~._interfaces: all public interfaces :type ~._interfaces: List[Interface] :ivar ~._private_interfaces: all internal interfaces which are not accessible from outside of unit :type _private_interfaces: List[Interface] :ivar ~._units: all units defined on this object :type ~._units: List[Unit] :ivar ~._params: all params defined on this object :type ~._params: List[Param] :ivar ~._constraints: additional HW specifications :ivar ~._parent: parent object :type ~._parent: Optional[Unit] :ivar ~._lazy_loaded: container of RTL object which were lazy loaded in implementation phase (this object has to be returned from :func:`~._to_rtl` of parent before it it's own objects) :ivar ~._shared_component_with: Optional tuple of the other :class:`hwt.synthesizer.unit.Unit` instance which produces an exactly same component in HDL and interface signal map current to shared and shared to current :type ~._shared_component_with: Optional[Tuple[Unit, Dict[Interface, Interface], Dict[Interface, Interface]]] :attention: if :func:`~._shared_component_with` is not None the body of this instance is not generated at all and the component from :func:`~._shared_component_with` is used instead :ivar ~._target_platform: meta-informations about target platform :ivar ~._name: a name of this component :ivar ~._hdl_module_name: a name of HDL module for this component (vhdl entity name, Verilog module name) """ _serializeDecision = None # properties which are used internally by this library _PROTECTED_NAMES = set([ "_PROTECTED_NAMES", "_name", "_hdl_module_name", "_interfaces", "_private_interfaces", "_units", "_params", "_parent", "_constraints", "_lazy_loaded", "_ctx", "_shared_component_with", "_target_platform", "_store_manager", ]) def __init__(self): self._parent = None self._name = None self._shared_component_with = None self._hdl_module_name = None self._lazy_loaded = [] self._ctx = RtlNetlist(self) self._constraints = HdlConstraintList() self._loadConfig() @internal def _loadInterface(self, i, isExtern): i._loadDeclarations() i._setAsExtern(isExtern) @internal def _loadDeclarations(self): """ Load all declarations from _decl() method, recursively for all interfaces/units. """ if not hasattr(self, "_interfaces"): self._interfaces = [] if not hasattr(self, "_private_interfaces"): self._private_interfaces = [] if not hasattr(self, "_units"): self._units = [] self._setAttrListener = self._declrCollector self._declr() self._setAttrListener = None for i in self._interfaces: self._loadInterface(i, True) # if I am a unit load subunits for u in self._units: u._loadDeclarations() @internal def _registerIntfInImpl(self, iName, intf): """ Register interface in implementation phase """ self._registerInterface(iName, intf, isPrivate=True) self._loadInterface(intf, False) intf._signalsForInterface(self._ctx, None, self._store_manager.name_scope) def _getDefaultName(self) -> str: return self.__class__.__name__ def _get_hdl_doc(self) -> Optional[str]: if self.__doc__ is not Unit.__doc__: return self.__doc__ @internal 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 _updateParamsFrom(self, otherObj, updater=_default_param_updater, exclude=None, prefix=""): """ :note: doc in :func:`hwt.synthesizer.interfaceLevel.propDeclCollector._updateParamsFrom` """ return PropDeclrCollector._updateParamsFrom(self, otherObj, updater, exclude, prefix) @internal 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}" )