def SignalItem(cls, si, ctx, declaration=False): if declaration: ctx = ctx.forSignal(si) v = si.defVal if si.virtualOnly: pass elif si.drivers: pass elif si.endpoints or si.simSensProcs: if not v.vldMask: raise SerializerException( "Signal %s is constant and has undefined value" % si.name) else: raise SerializerException( "Signal %s should be declared but it is not used" % si.name) t = si._dtype dimensions = [] while isinstance(t, HArray): # collect array dimensions dimensions.append(t.size) t = t.elmType s = "%s%s %s" % (getIndent(ctx.indent), cls.HdlType(t, ctx), si.name) if dimensions: # to make a space between name and dimensoins dimensions = list( map(lambda x: "[%s-1:0]" % cls.asHdl(toHVal(x), ctx), dimensions)) dimensions.append("") s += " ".join(reversed(dimensions)) if isinstance(v, RtlSignalBase): if v._const: return s + " = %s" % cls.asHdl(v, ctx) else: # default value has to be set by reset because it is only signal return s elif isinstance(v, Value): if v.vldMask: return s + " = %s" % cls.Value(v, ctx) else: return s else: raise NotImplementedError(v) else: return cls.get_signal_name(si, ctx)
def Value(cls, val, ctx: SerializerCtx): """ :param dst: is signal connected with value :param val: value object, can be instance of Signal or Value """ t = val._dtype if isinstance(val, RtlSignalBase): return cls.SignalItem(val, ctx) c = cls.Value_try_extract_as_const(val, ctx) if c: return c if isinstance(t, Slice): return cls.Slice_valAsHdl(t, val, ctx) elif isinstance(t, HArray): return cls.HArrayValAsHdl(t, val, ctx) elif isinstance(t, Bits): return cls.Bits_valAsHdl(t, val, ctx) elif isinstance(t, HBool): return cls.Bool_valAsHdl(t, val, ctx) elif isinstance(t, HEnum): return cls.HEnumValAsHdl(t, val, ctx) elif isinstance(t, Integer): return cls.Integer_valAsHdl(t, val, ctx) elif isinstance(t, String): return cls.String_valAsHdl(t, val, ctx) else: raise SerializerException( "can not resolve value serialization for %r" % (val))
def asHdl(cls, obj, ctx: HwtSerializerCtx): """ Convert object to HDL string :param obj: object to serialize :param ctx: HwtSerializerCtx instance """ if isinstance(obj, RtlSignalBase): return cls.SignalItem(obj, ctx) elif isinstance(obj, Value): return cls.Value(obj, ctx) else: try: serFn = obj.asHwt except AttributeError: serFn = None if serFn is not None: return serFn(cls, ctx) try: serFn = getattr(cls, obj.__class__.__name__) except AttributeError: serFn = None if serFn is not None: return serFn(obj, ctx) raise SerializerException("Not implemented for %r" % (obj))
def Assignment(cls, a, indent=0, default=None): dst = a.dst indentStr = getIndent(indent) ev = a.isEventDependent if a.indexes is not None: return "%syield (self.%s, %s, (%s,), %s)" % ( indentStr, dst.name, cls.Value(a.src), ", ".join( map(cls.asHdl, a.indexes)), ev) else: if not (dst._dtype == a.src._dtype): srcT = a.src._dtype dstT = dst._dtype if (isinstance(srcT, Bits) and isinstance(dstT, Bits) and srcT.bit_length() == dstT.bit_length() == 1): if srcT.forceVector != dstT.forceVector: if srcT.forceVector: return "%syield (self.%s, (%s)._getitem__val(simHInt(0)), %s)" % ( indentStr, dst.name, cls.Value(a.src), ev) else: return "%syield (self.%s, %s, (simHInt(0),), %s)" % ( indentStr, dst.name, cls.Value(a.src), ev) raise SerializerException( ("%s <= %s is not valid assignment\n" + " because types are different (%r; %r) ") % (cls.asHdl(dst), cls.Value( a.src), dst._dtype, a.src._dtype)) else: return "%syield (self.%s, %s, %s)" % (indentStr, dst.name, cls.Value(a.src), ev)
def as_hdl_Value(self, val): """ :param dst: is signal connected with value :param val: value object, can be instance of Signal or Value """ t = val._dtype if isinstance(val, RtlSignalBase): return self.as_hdl_SignalItem(val) # try to extract value as constant cc = self.constCache if cc is not None: if self.is_suitable_for_const_extract(val): c = cc.extract_const_val_as_const_var(val) if c is not None: return self.as_hdl(c) if isinstance(t, Slice): return self.as_hdl_SliceVal(val) elif isinstance(t, HArray): return self.as_hdl_HArrayVal(val) elif isinstance(t, Bits): return self.as_hdl_BitsVal(val) elif isinstance(t, HEnum): return self.as_hdl_HEnumVal(val) elif isinstance(t, String): return self.as_hdl_StringVal(val) else: raise SerializerException( "can not resolve value serialization for %r" % (val))
def _as_hdl_Assignment_auto_conversions(self, a: Assignment): dst = a.dst src = a.src dst_indexes = a.indexes if a.indexes is not None: dst_indexes = [self.as_hdl(x) for x in dst_indexes] correct = True else: if not (dst._dtype == a.src._dtype): srcT = a.src._dtype dstT = dst._dtype if (isinstance(srcT, Bits) and isinstance(dstT, Bits)): bl0 = srcT.bit_length() if bl0 == dstT.bit_length(): if bl0 == 1 and srcT.force_vector != dstT.force_vector: if srcT.force_vector: src = src[0] correct = True elif dstT.force_vector: dst_indexes = [ self.as_hdl_int(0), ] correct = True elif srcT.signed == dstT.signed: correct = True else: correct = True if not correct: raise SerializerException( ("%s <= %s is not valid assignment\n" " because types are different (%r; %r) ") % (dst, src, dst._dtype, a.src._dtype)) return dst, dst_indexes, self.as_hdl_Value(src)
def PortConnection(cls, pc, ctx): if pc.portItem._dtype != pc.sig._dtype: raise SerializerException( "Port map %s is nod valid (types does not match) (%s, %s)" % ("%s => %s" % (pc.portItem.name, cls.asHdl(pc.sig, ctx)), repr(pc.portItem._dtype), repr(pc.sig._dtype))) return ".%s(%s)" % (pc.portItem.name, cls.asHdl(pc.sig, ctx))
def toRtl(unitOrCls, name=None, serializer=VhdlSerializer): """ convert unit to rtl string using specified serializer """ if not isinstance(unitOrCls, Unit): u = unitOrCls() else: u = unitOrCls u._loadDeclarations() if name is not None: u._name = name globScope = serializer.getBaseNameScope() codeBuff = [] mouduleScopes = {} # unitCls : unitobj serializedClasses = {} # (unitCls, paramsValues) : unitObj # where paramsValues are dict name:value serializedConfiguredUnits = {} doSerialize = True for obj in u._toRtl(): doSerialize = serializer.serializationDecision( obj, serializedClasses, serializedConfiguredUnits) if doSerialize: if isinstance(obj, Entity): s = globScope.fork(1) s.setLevel(2) mouduleScopes[obj] = s sc = serializer.Entity(obj, s) elif isinstance(obj, Architecture): try: s = mouduleScopes[obj.entity] except KeyError: raise SerializerException( "Entity should be serialized before architecture of %s" % (obj.getEntityName())) sc = serializer.Architecture(obj, s) else: sc = serializer.asHdl(obj) codeBuff.append(sc) else: try: name = "(" + obj.name + ")" except AttributeError: name = "" codeBuff.append( serializer.comment( "Object of class %s%s was not serialized due its serializer mode" % (obj.__class__.__name__, name))) return serializer.formater("\n".join(codeBuff))
def HdlType_int(cls, typ, scope, declaration=False): ma = typ.max mi = typ.min noMax = ma is None noMin = mi is None if noMin: if noMax: return "INTEGER" else: raise SerializerException("If max is specified min has to be specified as well") else: if noMax: if mi == 0: return "NATURAL" elif mi == 1: return "POSITIVE" else: raise SerializerException("If max is specified min has to be specified as well") else: return "INTEGER RANGE %d to %d" % (mi, ma)
def as_hdl_Assignment(self, a: Assignment): _dst = dst = a.dst assert isinstance(dst, SignalItem) if a.indexes is not None: for i in a.indexes: if isinstance(i, SliceVal): i = i.__copy__() dst = dst[i] src_t = a.src._dtype dst_t = dst._dtype correct = False src = a.src if dst_t == src_t: correct = True else: src = a.src if (isinstance(dst_t, Bits) and isinstance(src_t, Bits)): # std_logic <-> std_logic_vector(0 downto 0) auto conversions if dst_t.bit_length() == src_t.bit_length() == 1: if dst_t.force_vector and not src_t.force_vector: dst = dst[0] correct = True elif not dst_t.force_vector and src_t.force_vector: src = src[0] correct = True elif src_t == BOOL: src = src._ternary(hBit(1), hBit(0)) correct = True elif not src_t.strict_width: if isinstance(src, Value): src = copy(src) if a.indexes: raise NotImplementedError() src._dtype = dst_t correct = True else: raise NotImplementedError() pass if correct: src = self.as_hdl(src) hdl_a = HdlStmAssign(src, self.as_hdl(dst)) hdl_a.is_blocking = _dst.virtual_only return hdl_a raise SerializerException( "%s = %s is not valid assignment\n" " because types are different (%r; %r) " % (dst, a.src, dst._dtype, a.src._dtype))
def Assignment(cls, a: Assignment, ctx): dst = a.dst assert isinstance(dst, SignalItem) # dstSignalType = verilogTypeOfSig(dst) indent_str = getIndent(ctx.indent) _dst = dst if a.indexes is not None: for i in a.indexes: if isinstance(i, SliceVal): i = i.__copy__() dst = dst[i] dstStr = cls.asHdl(dst, ctx) ver_sig_t = verilogTypeOfSig(_dst) if ver_sig_t == SIGNAL_TYPE.REG: evDep = False for driver in _dst.drivers: if driver._now_is_event_dependent: evDep = True break if not evDep or _dst.virtual_only: prefix = "" symbol = "=" else: prefix = "" symbol = "<=" elif ver_sig_t == SIGNAL_TYPE.WIRE: if a.parentStm is None: prefix = "assign " else: prefix = "" symbol = "=" else: ValueError(ver_sig_t) firstPartOfStr = "%s%s%s" % (indent_str, prefix, dstStr) src_t = a.src._dtype dst_t = dst._dtype srcStr = cls.Value(a.src, ctx) if dst_t == src_t \ or (isinstance(src_t, Bits) and isinstance(dst_t, Bits) and src_t.bit_length() == dst_t.bit_length() == 1): return "%s %s %s;" % (firstPartOfStr, symbol, srcStr) else: raise SerializerException("%s %s %s is not valid assignment\n" " because types are different (%r; %r) " % (dstStr, symbol, srcStr, dst._dtype, a.src._dtype))
def as_hdl_PortConnection(self, o: HdlPortItem): assert isinstance(o, HdlPortItem), o if o.dst._dtype != o.src._dtype: raise SerializerException( f"Port map {o.name:s} is not valid (types does not match) ({o.src._dtype}, {o.dst._dtype}) " f"{o.src} => {o.dst}") intern, outer = o.getInternSig(), o.getOuterSig() intern_hdl = self.as_hdl_Value(intern) intern_hdl.obj = o outer_hdl = self.as_hdl_Value(outer) pm = hdl_map_asoc(intern_hdl, outer_hdl) return pm
def HdlType_int(cls, typ, scope, declaration=False): ma = typ.max mi = typ.min noMax = ma is None noMin = mi is None if noMin: if noMax: return "SIM_INT" else: raise SerializerException( "If max is specified min has to be specified as well") else: if noMax: # [TODO] convert these to sim as well if mi == 0: return "UINT" elif mi == 1: return "PINT" else: raise SerializerException( "If max is specified min has to be specified as well") else: raise NotImplementedError()
def as_hdl(self, obj) -> iHdlObj: """ Convert any object to HDL AST :param obj: object to convert """ serFn = getattr(self, "as_hdl_" + obj.__class__.__name__, None) if serFn is not None: return serFn(obj) elif isinstance(obj, RtlSignalBase): return self.as_hdl_SignalItem(obj) else: raise SerializerException(self, "Not implemented for obj of", obj.__class__, obj)
def SignalItem(cls, si: SignalItem, ctx: SerializerCtx, declaration=False): if declaration: v = si.def_val if si.virtual_only: prefix = "VARIABLE" elif si.drivers: prefix = "SIGNAL" elif si.endpoints or si.simSensProcs: prefix = "CONSTANT" if not v.vld_mask: raise SerializerException( "Signal %s is constant and has undefined value" % si.name) else: raise SerializerException( "Signal %s should be declared but it is not used" % si.name) s = "%s%s %s: %s" % (getIndent( ctx.indent), prefix, si.name, cls.HdlType(si._dtype, ctx)) if isinstance(v, RtlSignalBase): if v._const: return s + " := %s" % cls.asHdl(v, ctx) else: # default value has to be set by reset # because it is only signal return s elif isinstance(v, Value): if v.vld_mask: return s + " := %s" % cls.Value(v, ctx) else: return s else: raise NotImplementedError(v) else: return cls.get_signal_name(si, ctx)
def SignalItem(cls, si, createTmpVarFn, declaration=False): if declaration: v = si.defaultVal if si.virtualOnly: prefix = "VARIABLE" elif si.drivers: prefix = "SIGNAL" elif si.endpoints or si.simSensProcs: prefix = "CONSTANT" if not v.vldMask: raise SerializerException( "Signal %s is constant and has undefined value" % si.name) else: raise SerializerException( "Signal %s should be declared but it is not used" % si.name) s = prefix + " %s : %s" % (si.name, cls.HdlType(si._dtype, createTmpVarFn)) if isinstance(v, RtlSignalBase): return s + " := %s" % cls.asHdl(v, createTmpVarFn) elif isinstance(v, Value): if si.defaultVal.vldMask: return s + " := %s" % cls.Value(si.defaultVal, createTmpVarFn) else: return s else: raise NotImplementedError(v) else: if si.hidden and hasattr(si, "origin"): return cls.asHdl(si.origin, createTmpVarFn) else: return si.name
def as_hdl_PortConnection(self, o: HdlPortItem): assert isinstance(o, HdlPortItem), o if o.dst._dtype != o.src._dtype: raise SerializerException( "Port map %s is not valid (types does not match) (%r, %r) " "%s => %s" % (o.name, o.src._dtype, o.dst._dtype, o.src, o.dst,) ) intern, outer = o.getInternSig(), o.getOuterSig() intern_hdl = self.as_hdl_Value(intern) intern_hdl.obj = o outer_hdl = self.as_hdl_Value(outer) pm = hdl_map_asoc(intern_hdl, outer_hdl) return pm
def Assignment(cls, a, ctx): dst = a.dst assert isinstance(dst, SignalItem) assert not dst.virtualOnly, "should not be required" typeOfDst = systemCTypeOfSig(dst) if a.indexes is not None: for i in a.indexes: dst = dst[i] if dst._dtype == a.src._dtype: return cls._Assignment(dst, typeOfDst, a.src, ctx) else: raise SerializerException( "%r <= %r is not valid assignment\n" " because types are different (%r; %r) " % (dst, a.src, dst._dtype, a.src._dtype))
def Assignment(cls, a: Assignment, ctx): dst = a.dst assert isinstance(dst, SignalItem) def valAsHdl(v): return cls.Value(v, ctx) # dstSignalType = verilogTypeOfSig(dst) assert not dst.virtualOnly if a._is_completly_event_dependent: prefix = "" symbol = "<=" else: if a.parentStm is None: prefix = "assign " else: prefix = "" symbol = "=" if a.indexes is not None: for i in a.indexes: if isinstance(i, SliceVal): i = i.clone() i.val = (i.val[0], i.val[1]) dst = dst[i] indent_str = getIndent(ctx.indent) dstStr = cls.asHdl(dst, ctx) firstPartOfStr = "%s%s%s" % (indent_str, prefix, dstStr) src_t = a.src._dtype dst_t = dst._dtype if dst_t == src_t \ or (isinstance(src_t, Bits) and isinstance(dst_t, Bits) and src_t.bit_length() == dst_t.bit_length() == 1): return "%s %s %s;" % (firstPartOfStr, symbol, valAsHdl(a.src)) else: raise SerializerException("%s %s %s is not valid assignment\n" " because types are different (%r; %r) " % (dstStr, symbol, valAsHdl(a.src), dst._dtype, a.src._dtype))
def Assignment(cls, a, ctx): dst = a.dst assert isinstance(dst, SignalItem) def valAsHdl(v): return cls.Value(v, ctx) if dst.virtualOnly: symbol = ":=" else: symbol = "<=" if a.indexes is not None: for i in a.indexes: if isinstance(i, SliceVal): i = i.clone() i.val = (i.val[0], i.val[1]) dst = dst[i] indent_str = getIndent(ctx.indent) dstStr = cls.asHdl(dst, ctx) src_t = a.src._dtype dst_t = dst._dtype if dst_t == src_t: return "%s%s %s %s" % (indent_str, dstStr, symbol, valAsHdl(a.src)) else: if (isinstance(dst_t, Bits) and isinstance(src_t, Bits) and dst_t.bit_length() == src_t.bit_length() == 1): if dst_t.forceVector and not src_t.forceVector: return "%s%s(0) %s %s" % (indent_str, dstStr, symbol, valAsHdl(a.src)) if not dst_t.forceVector and src_t.forceVector: return "%s%s %s %s(0)" % (indent_str, dstStr, symbol, valAsHdl(a.src)) raise SerializerException( "%s%s %s %s is not valid assignment\n" " because types are different (%r; %r) " % (indent_str, dstStr, symbol, valAsHdl(a.src), dst._dtype, a.src._dtype))
def ComponentInstance(cls, entity, ctx: VerilogSerializerCtx): with CurrentUnitSwap(ctx, entity.origin): portMaps = [] for pi in entity.ports: pm = PortMap.fromPortItem(pi) portMaps.append(pm) genericMaps = [] for g in entity.generics: gm = MapExpr(g, g._val) genericMaps.append(gm) if len(portMaps) == 0: raise SerializerException("Incomplete component instance") # [TODO] check component instance name return cls.componentInstanceTmpl.render( indent=getIndent(ctx.indent), instanceName=entity._name, entity=entity, portMaps=[cls.PortConnection(x, ctx) for x in portMaps], genericMaps=[cls.MapExpr(x, ctx) for x in genericMaps])
def as_hdl_Assignment(self, a: Assignment): dst = a.dst assert isinstance(dst, SignalItem) # assert not dst.virtual_only, "should not be required" if a.indexes is not None: for i in a.indexes: dst = dst[i] typeOfDst = systemCTypeOfSig(dst) if dst.virtual_only and isinstance(a.src, Operator): assert a.src.operator == AllOps.CONCAT return self._as_hdl_Assignment(dst, typeOfDst, a.src.operands) if dst._dtype == a.src._dtype or (isinstance(dst._dtype, Bits) and a.src._dtype == BOOL): return self._as_hdl_Assignment(dst, typeOfDst, a.src) else: raise SerializerException( "%r <= %r is not valid assignment\n" " because types are different (%r; %r) " % (dst, a.src, dst._dtype, a.src._dtype))
def Assignment(cls, a: Assignment, ctx: SerializerCtx): dst = a.dst indentStr = getIndent(ctx.indent) ev = a._is_completly_event_dependent srcStr = "%s" % cls.Value(a.src, ctx) if a.indexes is not None: return "%sio.%s = (%s, (%s,), %s)" % ( indentStr, dst.name, srcStr, ", ".join(map(lambda x: cls.asHdl(x, ctx), a.indexes)), ev) else: if not (dst._dtype == a.src._dtype): srcT = a.src._dtype dstT = dst._dtype if (isinstance(srcT, Bits) and isinstance(dstT, Bits) and srcT.bit_length() == dstT.bit_length() == 1): if srcT.forceVector != dstT.forceVector: _0 = cls.Value(toHVal(0), ctx) if srcT.forceVector: return "%sio.%s = ((%s)._getitem__val(%s), %s)"\ % (indentStr, dst.name, srcStr, _0, ev) else: return "%sio.%s = (%s, (%s,), %s)" % ( indentStr, dst.name, srcStr, _0, ev) raise SerializerException( ("%s <= %s is not valid assignment\n" " because types are different (%r; %r) ") % (cls.asHdl(dst, ctx), srcStr, dst._dtype, a.src._dtype)) else: return "%sio.%s = (%s, %s)" % ( indentStr, dst.name, srcStr, ev)
def Architecture_var(cls, v, serializerVars, extraTypes, extraTypes_serialized, ctx, childCtx): """ :return: list of extra discovered processes """ t = v._dtype # if type requires extra definition if isinstance(t, HArray) and v.defVal.vldMask: if v.drivers: raise SerializerException("Verilog does not support RAMs" " with initialized value") eProcs, eVars = cls.hardcodeRomIntoProcess(v) for _v in eVars: _procs = cls.Architecture_var(_v, serializerVars, extraTypes, extraTypes_serialized, ctx, childCtx) eProcs.extend(_procs) return eProcs v.name = ctx.scope.checkedName(v.name, v) serializedVar = cls.SignalItem(v, childCtx, declaration=True) serializerVars.append(serializedVar) return []
def Assignment(cls, a, createTmpVarFn): dst = a.dst assert isinstance(dst, SignalItem) asHdl = lambda obj : cls.asHdl(obj, createTmpVarFn) valAsHdl = lambda v: cls.Value(v, createTmpVarFn) if dst.virtualOnly: symbol = ":=" else: symbol = "<=" if a.indexes is not None: for i in a.indexes: if isinstance(i, SliceVal): i = i.clone() i.val = (i.val[0] + 1, i.val[1]) dst = dst[i] if dst._dtype == a.src._dtype: return "%s %s %s" % (asHdl(dst), symbol, valAsHdl(a.src)) else: srcT = a.src._dtype dstT = dst._dtype if isinstance(srcT, Bits) and isinstance(dstT, Bits): sLen = srcT.bit_length() dLen = dstT.bit_length() if sLen == dLen: if sLen == 1 and srcT.forceVector != dstT.forceVector: if srcT.forceVector: return "%s %s %s(0)" % (asHdl(dst), symbol, valAsHdl(a.src)) else: return "%s(0) %s %s" % (asHdl(dst), symbol, valAsHdl(a.src)) elif srcT.signed is not dstT.signed: return "%s %s %s" % (asHdl(dst), symbol, valAsHdl(a.src._convSign(dstT.signed))) raise SerializerException("%s %s %s is not valid assignment\n because types are different (%s; %s) " % (asHdl(dst), symbol, valAsHdl(a.src), repr(dst._dtype), repr(a.src._dtype)))
def toRtlAndSave(unit, folderName='.', name=None, serializer=VhdlSerializer): unit._loadDeclarations() os.makedirs(folderName, exist_ok=True) files = UniqList() if name is not None: unit._name = name globScope = serializer.getBaseNameScope() mouduleScopes = {} # unitCls : unitobj serializedClasses = {} # (unitCls, paramsValues) : unitObj # where paramsValues are dict name:value serializedConfiguredUnits = {} doSerialize = True for obj in unit._toRtl(): doSerialize = serializer.serializationDecision( obj, serializedClasses, serializedConfiguredUnits) if doSerialize: if isinstance(obj, Entity): # we need to serialize before we take name, before name can change s = globScope.fork(1) s.setLevel(2) mouduleScopes[obj] = s sc = serializer.Entity(obj, s) fName = obj.name + serializer.fileExtension fileMode = 'w' elif isinstance(obj, Architecture): try: s = mouduleScopes[obj.entity] except KeyError: raise SerializerException( "Entity should be serialized before architecture of %s" % (obj.getEntityName())) sc = serializer.Architecture(obj, s) fName = obj.getEntityName() + serializer.fileExtension fileMode = 'a' else: if hasattr(obj, "_hdlSources"): fName = None for fn in obj._hdlSources: if isinstance(fn, str): shutil.copy2(fn, folderName) files.append(fn) else: sc = serializer.asHdl(obj) if fName is not None: fp = os.path.join(folderName, fName) files.append(fp) with open(fp, fileMode) as f: if fileMode == 'a': f.write("\n") f.write(serializer.formater(sc)) return files
def Assignment(cls, a, ctx): dst = a.dst assert isinstance(dst, SignalItem) def valAsHdl(v): return cls.Value(v, ctx) if dst.virtual_only: symbol = ":=" else: symbol = "<=" if a.indexes is not None: for i in a.indexes: if isinstance(i, SliceVal): i = i.__copy__() dst = dst[i] indent_str = getIndent(ctx.indent) dstStr = cls.asHdl(dst, ctx) src_t = a.src._dtype dst_t = dst._dtype if dst_t == src_t: return "%s%s %s %s" % (indent_str, dstStr, symbol, valAsHdl(a.src)) else: correct = False src = a.src if (isinstance(dst_t, Bits) and isinstance(src_t, Bits)): if dst_t.bit_length() == src_t.bit_length() == 1: if dst_t.force_vector and not src_t.force_vector: dstStr = "%s(0)" % (dstStr) srcStr = valAsHdl(a.src) correct = True elif not dst_t.force_vector and src_t.force_vector: srcStr = "%s(0)" % valAsHdl(src) correct = True elif src_t == BOOL: srcStr = "'1' WHEN %s ELSE '0'" % valAsHdl(src) correct = True elif not src_t.strict_width: if isinstance(src, Value): _src = copy(src) if a.indexes: raise NotImplementedError() _src._dtype = dst_t srcStr = cls.Value(_src, ctx) correct = True else: raise NotImplementedError() pass if correct: return "%s%s %s %s" % (indent_str, dstStr, symbol, srcStr) raise SerializerException( "%s%s %s %s is not valid assignment\n" " because types are different (%r; %r) " % (indent_str, dstStr, symbol, valAsHdl( a.src), dst._dtype, a.src._dtype))
def as_hdl_SignalItem(self, si: Union[SignalItem, HdlIdDef], declaration=False): if declaration: if isinstance(si, HdlIdDef): var = copy(si) si = si.origin else: var = HdlIdDef() var.name = si.name var.origin = si var.value = si._val var.type = si._dtype var.is_const = si._const v = var.value if isinstance(si, RtlSignalBase): if si.virtual_only: var.is_latched = True elif si.drivers or var.direction != HdlDirection.UNKNOWN: # has drivers or is port/param pass elif si.endpoints: if not v.vld_mask: raise SerializerException( "Signal %s is constant and has undefined value" % si.name) var.is_const = True else: raise SerializerException( "Signal %s should be declared but it is not used" % si.name) if v is None: pass elif isinstance(v, RtlSignalBase): if v._const: var.value = self.as_hdl(v) else: # default value has to be set by reset, # because it is not resolvable in compile time var.value = None pass elif isinstance(v, Value): if v.vld_mask or var.is_const: orig_const_cache = self.constCache try: self.constCache = None var.value = self.as_hdl_Value(v) finally: self.constCache = orig_const_cache else: # remove value if it is entirely undefined var.value = None else: raise NotImplementedError(v) var.type = self.as_hdl_HdlType(var.type) return var else: if si.hidden and hasattr(si, "origin"): # hidden signal, render it's driver instead return self.as_hdl(si.origin) return HdlValueId(si.name, obj=si)
def toRtl(unitOrCls: Unit, name: str=None, serializer: GenericSerializer=VhdlSerializer, targetPlatform=DummyPlatform(), saveTo: str=None): """ Convert unit to RTL using specified serializer :param unitOrCls: unit instance or class, which should be converted :param name: name override of top unit (if is None name is derived form class name) :param serializer: serializer which should be used for to RTL conversion :param targetPlatform: metainformatins about target platform, distributed on every unit under _targetPlatform attribute before Unit._impl() is called :param saveTo: directory where files should be stored If None RTL is returned as string. :raturn: if saveTo returns RTL string else returns list of file names which were created """ if not isinstance(unitOrCls, Unit): u = unitOrCls() else: u = unitOrCls u._loadDeclarations() if name is not None: assert isinstance(name, str) u._name = name globScope = serializer.getBaseNameScope() mouduleScopes = {} # unitCls : unitobj serializedClasses = {} # (unitCls, paramsValues) : unitObj # where paramsValues are dict name:value serializedConfiguredUnits = {} doSerialize = True createFiles = saveTo is not None if createFiles: os.makedirs(saveTo, exist_ok=True) files = UniqList() else: codeBuff = [] for obj in u._toRtl(targetPlatform): doSerialize = serializer.serializationDecision( obj, serializedClasses, serializedConfiguredUnits) if doSerialize: if isinstance(obj, Entity): s = globScope.fork(1) s.setLevel(2) ctx = serializer.getBaseContext() ctx.scope = s mouduleScopes[obj] = ctx ctx.currentUnit = obj.origin sc = serializer.Entity(obj, ctx) if createFiles: fName = obj.name + serializer.fileExtension fileMode = 'w' elif isinstance(obj, Architecture): try: ctx = mouduleScopes[obj.entity] except KeyError: raise SerializerException( "Entity should be serialized" " before architecture of %s" % (obj.getEntityName())) sc = serializer.Architecture(obj, ctx) if createFiles: fName = obj.getEntityName() + serializer.fileExtension fileMode = 'a' else: if hasattr(obj, "_hdlSources"): for fn in obj._hdlSources: if isinstance(fn, str): shutil.copy2(fn, saveTo) files.append(fn) continue else: sc = serializer.asHdl(obj) if sc: if createFiles: fp = os.path.join(saveTo, fName) files.append(fp) with open(fp, fileMode) as f: if fileMode == 'a': f.write("\n") f.write( serializer.formatter(sc) ) else: codeBuff.append(sc) elif not createFiles: try: name = '"%s"' % obj.name except AttributeError: name = "" codeBuff.append(serializer.comment( "Object of class %s, %s was not serialized as specified" % ( obj.__class__.__name__, name))) if createFiles: return files else: return serializer.formatter( "\n".join(codeBuff) )
def SignalItem(cls, si, ctx, declaration=False): sigType = systemCTypeOfSig(si) if declaration: if sigType is SIGNAL_TYPE.REG: fmt = "%s%s %s" else: fmt = "%ssc_signal<%s> %s" ctx = ctx.forSignal(si) v = si.def_val if si.virtual_only: raise NotImplementedError() elif si.drivers: pass elif si.endpoints or si.simSensProcs: if not v.vld_mask: raise SerializerException( "Signal %s is constant and has undefined value" % si.name) else: raise SerializerException( "Signal %s should be declared but it is not used" % si.name) t = si._dtype dimensions = [] while isinstance(t, HArray): # collect array dimensions dimensions.append(t.size) t = t.element_t s = fmt % (getIndent(ctx.indent), cls.HdlType(t, ctx), si.name) if dimensions: # to make a space between name and dimensoins dimensions = [ "[%s]" % cls.asHdl(toHVal(x), ctx) for x in dimensions ] dimensions.append("") s += " ".join(reversed(dimensions)) if isinstance(v, RtlSignalBase): if v._const: return s + " = %s" % cls.asHdl(v, ctx) else: # default value has to be set by reset # because it is only signal return s elif isinstance(v, Value): if si.def_val.vld_mask: return s + " = %s" % cls.Value(v, ctx) else: return s else: raise NotImplementedError(v) else: if si.hidden and hasattr(si, "origin"): return cls.asHdl(si.origin, ctx) else: if ctx.isTarget or sigType is SIGNAL_TYPE.REG: return si.name else: return "%s.read()" % si.name