def Architecture(cls, arch, ctx): serializerVars = [] procs = [] extraTypes = set() extraTypes_serialized = [] arch.variables.sort(key=lambda x: (x.name, x._instId)) arch.componentInstances.sort(key=lambda x: x._name) childCtx = ctx.withIndent() extraProcesses = [] for v in arch.variables: _eProc = cls.Architecture_var(v, serializerVars, extraTypes, extraTypes_serialized, ctx, childCtx) extraProcesses.extend(_eProc) arch.processes.extend(extraProcesses) arch.processes.sort(key=lambda x: (x.name, maxStmId(x))) for p in arch.processes: procs.append(cls.HWProcess(p, childCtx)) # architecture names can be same for different entities # arch.name = scope.checkedName(arch.name, arch, isGlobal=True) componentInstances = list( map(lambda c: cls.ComponentInstance(c, childCtx), arch.componentInstances)) return cls.moduleBodyTmpl.render(indent=getIndent(ctx.indent), entityName=arch.getEntityName(), name=arch.name, variables=serializerVars, extraTypes=extraTypes_serialized, processes=procs, componentInstances=componentInstances)
def reduceProcesses(processes): """ Try to merge processes as much is possible :param processes: list of processes instances """ # sort to make order of merging same deterministic processes.sort(key=lambda x: (x.name, maxStmId(x)), reverse=True) # now try to reduce processes with nearly same structure of statements into one # to minimize number of processes for _, procs in groupedby(processes, lambda p: p.rank): for iA, pA in enumerate(procs): if pA is None: continue for iB, pB in enumerate(islice(procs, iA + 1, None)): if pB is None: continue try: pA = tryToMerge(pA, pB) except IncompatibleStructure: continue procs[iA + 1 + iB] = None # procs[iA] = pA for p in procs: if p is not None: yield p
def Architecture(cls, arch: Architecture, ctx: SerializerCtx): cls.Entity_prepare(arch.entity, ctx, serialize=False) variables = [] procs = [] extraTypes = set() extraTypes_serialized = [] arch.variables.sort(key=lambda x: (x.name, x._instId)) arch.processes.sort(key=lambda x: (x.name, maxStmId(x))) arch.componentInstances.sort(key=lambda x: x._name) ports = list( map(lambda p: (p.name, cls.HdlType(p._dtype, ctx)), arch.entity.ports)) for v in arch.variables: t = v._dtype # if type requires extra definition if isinstance(t, HEnum) and t not in extraTypes: extraTypes.add(v._dtype) extraTypes_serialized.append( cls.HdlType(t, ctx, declaration=True)) v.name = ctx.scope.checkedName(v.name, v) variables.append(v) childCtx = copy(ctx) childCtx.constCache = ConstCache(ctx.scope.checkedName) def serializeVar(v): dv = evalParam(v.defVal) if isinstance(dv, HEnumVal): dv = "%s.%s" % (dv._dtype.name, dv.val) else: dv = cls.Value(dv, ctx) return v.name, cls.HdlType(v._dtype, childCtx), dv for p in arch.processes: procs.append(cls.HWProcess(p, childCtx)) constants = [] for c in sorted(childCtx.constCache._cache.items(), key=lambda x: x[1], reverse=True): constants.append((c[1], cls.Value(c[0], ctx))) return unitTmpl.render( name=arch.getEntityName(), constants=constants, ports=ports, signals=list(map(serializeVar, variables)), extraTypes=extraTypes_serialized, processes=procs, processObjects=arch.processes, processesNames=map(lambda p: p.name, arch.processes), componentInstances=arch.componentInstances, isOp=lambda x: isinstance(x, Operator), sensitivityByOp=sensitivityByOp, serialize_io=cls.sensitivityListItem, )
def Architecture(cls, arch, scope): variables = [] procs = [] extraTypes = set() extraTypes_serialized = [] arch.variables.sort(key=lambda x: x.name) arch.processes.sort(key=lambda x: (x.name, maxStmId(x))) arch.componentInstances.sort(key=lambda x: x._name) for v in arch.variables: t = v._dtype # if type requires extra definition if isinstance(t, Enum) and t not in extraTypes: extraTypes.add(v._dtype) extraTypes_serialized.append( cls.HdlType(t, scope, declaration=True)) v.name = scope.checkedName(v.name, v) variables.append(v) def serializeVar(v): dv = evalParam(v.defaultVal) if isinstance(dv, EnumVal): dv = "%s.%s" % (dv._dtype.name, dv.val) else: dv = cls.Value(dv) return v.name, cls.HdlType(v._dtype), dv for p in arch.processes: procs.append(cls.HWProcess(p, scope, 0)) # architecture names can be same for different entities # arch.name = scope.checkedName(arch.name, arch, isGlobal=True) return unitTmpl.render({ "name": arch.getEntityName(), "ports": list( map(lambda p: (p.name, cls.HdlType(p._dtype)), arch.entity.ports)), "signals": list(map(serializeVar, variables)), "extraTypes": extraTypes_serialized, "processes": procs, "processObjects": arch.processes, "processesNames": map(lambda p: p.name, arch.processes), "componentInstances": arch.componentInstances, "isOp": lambda x: isinstance(x, Operator), "sensitivityByOp": sensitivityByOp })
def Architecture(cls, arch: Architecture, ctx: HwtSerializerCtx): variables = [] procs = [] extraTypes = set() extraTypes_serialized = [] arch.variables.sort(key=lambda x: (x.name, x._instId)) arch.processes.sort(key=lambda x: (x.name, maxStmId(x))) arch.componentInstances.sort(key=lambda x: x._name) for v in arch.variables: t = v._dtype # if type requires extra definition if isinstance(t, HEnum) and t not in extraTypes: extraTypes.add(v._dtype) extraTypes_serialized.append( cls.HdlType(t, ctx, declaration=True)) v.name = ctx.scope.checkedName(v.name, v) variables.append(v) childCtx = ctx.withIndent(2) childCtx.constCache = ConstCache(ctx.scope.checkedName) def serializeVar(v): dv = v.def_val if isinstance(dv, HEnumVal): dv = "%s.%s" % (dv._dtype.name, dv.val) else: dv = cls.Value(dv, childCtx) return v.name, cls.HdlType(v._dtype, childCtx), dv for p in arch.processes: procs.append(cls.HWProcess(p, childCtx)) constants = [] const_cache = childCtx.constCache childCtx.constCache = None for cVal, cName in sorted(const_cache._cache.items(), key=lambda x: x[1], reverse=True): constants.append((cName, cls.Value(cVal, childCtx))) portNames = [p.name for p in arch.entity.ports] portToLocalsRow = "%s = %s" % ( ", ".join(portNames), ", ".join(["self." + n for n in portNames])) return unitBodyTmpl.render( DIRECTION_IN=DIRECTION.IN, name=arch.getEntityName(), portToLocalsRow=portToLocalsRow, constants=constants, signals=[serializeVar(v) for v in variables], extraTypes=extraTypes_serialized, processes=procs, componentInstances=arch.componentInstances, )
def create_HdlModuleDef(self, target_platform: DummyPlatform, store_manager: "StoreManager"): """ Generate a module body (architecture) for this module * Resolve name collisions * Convert netlist representation to HdlProcesses * Remove unconnected * Mark visibility of signals """ removeUnconnectedSignals(self) markVisibilityOfSignalsAndCheckDrivers(self.signals, self.interfaces) for proc in target_platform.beforeHdlArchGeneration: proc(self) ns = store_manager.name_scope mdef = HdlModuleDef() mdef.dec = self.ent mdef.module_name = HdlValueId(self.ent.name, obj=self.ent) mdef.name = "rtl" processes = sorted(statements_to_HdlStatementBlocks(self.statements), key=lambda x: (x.name, maxStmId(x))) # add signals, variables etc. in architecture for s in sorted((s for s in self.signals if not s.hidden and s not in self.interfaces.keys()), key=lambda x: (x.name, x._instId)): v = HdlIdDef() v.origin = s s.name = v.name = ns.checked_name(s.name, s) v.type = s._dtype v.value = s.def_val v.is_const = s._const mdef.objs.append(v) for p in processes: p.name = ns.checked_name(p.name, p) mdef.objs.extend(processes) # instantiate subUnits in architecture for u in self.subUnits: ci = HdlCompInst() ci.origin = u ci.module_name = HdlValueId(u._ctx.ent.name, obj=u._ctx.ent) ci.name = HdlValueId(ns.checked_name(u._name + "_inst", ci), obj=u) e = u._ctx.ent ci.param_map.extend(e.params) ci.port_map.extend(e.ports) mdef.objs.append(ci) self.arch = mdef return mdef
def Architecture(cls, arch: Architecture, ctx): with CurrentUnitSwap(ctx, arch.entity.origin): variables = [] procs = [] extraTypes = set() extraTypes_serialized = [] arch.variables.sort(key=lambda x: (x.name, x._instId)) arch.processes.sort(key=lambda x: (x.name, maxStmId(x))) arch.components.sort(key=lambda x: x.name) arch.componentInstances.sort(key=lambda x: x._name) childCtx = ctx.withIndent() for v in arch.variables: t = v._dtype # if type requires extra definition if isinstance(t, (HEnum, HArray)) and t not in extraTypes: extraTypes.add(v._dtype) extraTypes_serialized.append( cls.HdlType(t, childCtx, declaration=True)) v.name = ctx.scope.checkedName(v.name, v) serializedVar = cls.SignalItem(v, childCtx, declaration=True) variables.append(serializedVar) for p in arch.processes: procs.append(cls.HWProcess(p, childCtx)) # architecture names can be same for different entities # arch.name = scope.checkedName(arch.name, arch, isGlobal=True) uniqComponents = list( map(lambda x: x[1][0], groupedby(arch.components, lambda c: c.name))) uniqComponents.sort(key=lambda c: c.name) components = list( map(lambda c: cls.Component(c, childCtx), uniqComponents)) componentInstances = list( map(lambda c: cls.ComponentInstance(c, childCtx), arch.componentInstances)) return cls.architectureTmpl.render( indent=getIndent(ctx.indent), entityName=arch.getEntityName(), name=arch.name, variables=variables, extraTypes=extraTypes_serialized, processes=procs, components=components, componentInstances=componentInstances)
def Architecture(cls, arch, scope): variables = [] procs = [] extraTypes = set() extraTypes_serialized = [] arch.variables.sort(key=lambda x: x.name) arch.processes.sort(key=lambda x: (x.name, maxStmId(x))) arch.components.sort(key=lambda x: x.name) arch.componentInstances.sort(key=lambda x: x._name) def createTmpVarFn(suggestedName, dtype): raise NotImplementedError() for v in arch.variables: t = v._dtype # if type requires extra definition if isinstance(t, (Enum, Array)) and t not in extraTypes: extraTypes.add(v._dtype) extraTypes_serialized.append( cls.HdlType(t, createTmpVarFn, scope, declaration=True)) v.name = scope.checkedName(v.name, v) serializedVar = cls.SignalItem(v, createTmpVarFn, declaration=True) variables.append(serializedVar) for p in arch.processes: procs.append(cls.HWProcess(p, scope)) # architecture names can be same for different entities # arch.name = scope.checkedName(arch.name, arch, isGlobal=True) uniqComponents = list( map(lambda x: x[1][0], groupedby(arch.components, lambda c: c.name))) uniqComponents.sort(key=lambda c: c.name) components = list( map(lambda c: cls.Component(c, createTmpVarFn), uniqComponents)) componentInstances = list( map(lambda c: cls.ComponentInstance(c, createTmpVarFn, scope), arch.componentInstances)) return architectureTmpl.render({ "entityName": arch.getEntityName(), "name": arch.name, "variables": variables, "extraTypes": extraTypes_serialized, "processes": procs, "components": components, "componentInstances": componentInstances })
def Architecture(cls, arch, ctx): serializerVars = [] procs = [] extraTypes = set() extraTypes_serialized = [] arch.variables.sort(key=lambda x: (x.name, x._instId)) arch.componentInstances.sort(key=lambda x: x._name) childCtx = ctx.withIndent() ports = list( map(lambda pi: cls.PortItem(pi, childCtx), arch.entity.ports)) extraProcesses = [] for v in arch.variables: cls.Architecture_var(v, serializerVars, extraTypes, extraTypes_serialized, ctx, childCtx) arch.processes.extend(extraProcesses) arch.processes.sort(key=lambda x: (x.name, maxStmId(x))) for p in arch.processes: procs.append(cls.HWProcess(p, childCtx)) # architecture names can be same for different entities # arch.name = scope.checkedName(arch.name, arch, isGlobal=True) processesSensitivity = [] sensitivityCtx = ctx.forSensitivityList() for p in arch.processes: sens = list( map(lambda s: cls.asHdl(s, sensitivityCtx), p.sensitivityList)) processesSensitivity.append((p.name, sens)) return cls.moduleTmpl.render( processesSensitivity=processesSensitivity, name=arch.getEntityName(), ports=ports, signals=serializerVars, extraTypes=extraTypes_serialized, processes=procs, processObjects=arch.processes, componentInstances=arch.componentInstances, DIRECTION=DIRECTION, )
def _as_hdl_HdlModuleDef(self, new_m: HdlModuleDef) -> HdlModuleDef: # with WithNameScope(self, # self.name_scope.get_child(o.module_name.val)): hdl_types, hdl_variables, processes, component_insts = \ ToBasicHdlSimModel.split_HdlModuleDefObjs(self, new_m.objs) # [TODO] sorting not required as it should be done in _to_rtl() hdl_variables.sort(key=lambda x: (x.name, x.origin._instId)) processes.sort(key=lambda x: (x.name, maxStmId(x))) component_insts.sort(key=lambda x: x.name) types = set() _hdl_variables = [] extraVars = [] ns = self.name_scope def createTmpVarInCurrentModuleBody(suggestedName, dtype, const=False, def_val=None): # create a new tmp variable in current module s = RtlSignal(None, None, dtype, virtual_only=True) s.name = ns.checked_name(suggestedName, s) s.hidden = False s._const = const if def_val is not None: s.def_val = def_val s._set_def_val() as_hdl = self.as_hdl_SignalItem(s, declaration=True) extraVars.append(s) _hdl_variables.append(as_hdl) return s with CreateTmpVarFnSwap(self, createTmpVarInCurrentModuleBody): return self._as_hdl_HdlModuleDef_body(new_m, types, hdl_types, hdl_variables, _hdl_variables, processes, component_insts, extraVars)