Source code for hwt.serializer.generic.value
from copy import copy
from typing import Union
from hdlConvertorAst.hdlAst._defs import HdlIdDef
from hdlConvertorAst.hdlAst._expr import HdlValueId, HdlValueInt, HdlDirection
from hwt.hdl.types.array import HArray
from hwt.hdl.types.bits import Bits
from hwt.hdl.types.defs import INT, BOOL, FLOAT64
from hwt.hdl.types.enum import HEnum
from hwt.hdl.types.float import HFloat
from hwt.hdl.types.slice import HSlice
from hwt.hdl.types.string import HString
from hwt.hdl.value import HValue
from hwt.hdl.variables import SignalItem
from hwt.serializer.exceptions import SerializerException
from hwt.synthesizer.rtlLevel.mainBases import RtlSignalBase
[docs]class ToHdlAst_Value():
[docs] def as_hdl_Value(self, val):
"""
:param dst: is signal connected with value
:param val: value object, can be instance of Signal or HValue
"""
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, HSlice):
return self.as_hdl_HSliceVal(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, HString):
return self.as_hdl_HStringVal(val)
elif isinstance(t, HFloat):
return self.as_hdl_HFloatVal(val)
else:
raise SerializerException(
"can not resolve value serialization for %r"
% (val))
[docs] def as_hdl_int(self, val: int):
assert isinstance(val, int), val
return HdlValueInt(val, None, None)
[docs] def as_hdl_IntegerVal(self, val):
return self.as_hdl_int(int(val.val))
[docs] def as_hdl_BitsVal(self, val):
t = val._dtype
if t == INT:
return self.as_hdl_IntegerVal(val)
elif t == BOOL:
return self.as_hdl_BoolVal(val)
w = t.bit_length()
return self.as_hdl_BitString(val.val, w, t.force_vector,
val.vld_mask, t.signed)
[docs] def as_hdl_HStringVal(self, val):
return val.val
[docs] def as_hdl_HFloatVal(self, val):
if val._dtype != FLOAT64:
raise NotImplementedError(val._dtype)
return float(val)
[docs] 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(
f"Signal {si.name:s} is constant and has undefined value")
var.is_const = True
else:
raise SerializerException(
f"Signal {si.name:s} should be declared but it is not used")
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, HValue):
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 si.origin is not None:
# hidden signal, render it's driver instead
return self.as_hdl(si.origin)
return HdlValueId(si.name, obj=si)