from io import StringIO
import math
from typing import List, Tuple, Union
from hdlConvertorAst.hdlAst import HdlValueId
from hdlConvertorAst.hdlAst._defs import HdlIdDef
from hdlConvertorAst.to.vhdl.vhdl2008 import ToVhdl2008
from hdlConvertorAst.translate.verilog_to_basic_hdl_sim_model.utils import hdl_call
from hwt.doc_markers import internal
from hwt.hdl.types.bits import Bits
from hwt.hdl.types.defs import BOOL, STR, BIT, INT
from hwt.hdl.types.hdlType import HdlType
from hwt.serializer.store_manager import SaveToFilesFlat
from hwt.serializer.vhdl import Vhdl2008Serializer, ToHdlAstVhdl2008
from hwt.synthesizer.dummyPlatform import DummyPlatform
from hwt.synthesizer.interface import Interface
from hwt.synthesizer.interfaceLevel.unitImplHelpers import getSignalName
from hwt.synthesizer.param import Param
from hwt.synthesizer.rtlLevel.mainBases import RtlSignalBase
from hwt.synthesizer.rtlLevel.rtlSignal import RtlSignal
from hwt.synthesizer.unit import Unit
from hwt.synthesizer.utils import to_rtl
from ipCorePackager.intfIpMeta import VALUE_RESOLVE
from ipCorePackager.otherXmlObjs import Value
from ipCorePackager.packager import IpCorePackager
[docs]class ToHdlAstVivadoTclExpr(ToHdlAstVhdl2008):
_spirit_decode = HdlValueId("spirit:decode")
_id = HdlValueId("id")
[docs] def as_hdl_SignalItem(self, si, declaration=False):
assert(declaration == False)
if si.hidden:
assert si.origin is not None, si
return self.as_hdl(si.origin)
else:
id_ = hdl_call(self._id, [f'MODELPARAM_VALUE.{si.name}'])
return hdl_call(self._spirit_decode, [id_])
[docs]class IpPackager(IpCorePackager):
"""
IP-core packager
:summary: Packs HDL, constraint and other files to IP-Core package
for distribution and simple integration
"""
[docs] def __init__(self, topUnit: Unit, name: str=None,
extra_files: List[str]=[],
serializer_cls=Vhdl2008Serializer,
target_platform=DummyPlatform()):
"""
:param topObj: :class:`hwt.synthesizer.unit.Unit` instance of top component
:param name: optional name of top
:param extra_files: list of extra HDL/constrain file names for files
which should be distributed in this IP-core
(\*.v - verilog, \*.sv,\*.svh -system verilog, \*.vhd - vhdl, \*.xdc - XDC)
:param serializer: serializer which specifies target HDL language
:param target_platform: specifies properties of target platform, like available resources, vendor, etc.
"""
if not name:
name = topUnit._getDefaultName()
super(IpPackager, self).__init__(
topUnit, name, extra_files)
self.serializer = serializer_cls
self.target_platform = target_platform
[docs] @internal
def toHdlConversion(self, top, topName: str, saveTo: str) -> List[str]:
"""
:param top: object which is represenation of design
:param topName: name which should be used for ipcore
:param saveTo: path of directory where generated files should be stored
:return: list of file namens in correct compile order
"""
ser = self.serializer
store = SaveToFilesFlat(ser, saveTo)
to_rtl(top, name=topName, store_manager=store,
target_platform=self.target_platform)
return store.files
[docs] @internal
def paramToIpValue(self, idPrefix: str, g: HdlIdDef, resolve) -> Value:
val = Value()
val.id = idPrefix + g.name
if resolve is not VALUE_RESOLVE.NONE:
val.resolve = resolve
v = g.value
t = g.type
def getVal():
if v.vld_mask:
return v.val
else:
return 0
def bitString(w):
val.format = "bitString"
digits = math.ceil(w / 4)
val.text = ('0x%0' + str(digits) + 'X') % getVal()
val.bitStringLength = str(w)
if t == BOOL:
val.format = "bool"
val.text = str(bool(getVal())).lower()
elif t == INT:
val.format = "long"
val.text = str(getVal())
elif t == STR:
val.format = "string"
val.text = v.val
elif isinstance(t, Bits):
bitString(t.bit_length())
else:
raise NotImplementedError(
f"Not implemented for datatype {t}")
return val
[docs] @internal
def getParamPhysicalName(self, p: HdlIdDef):
return p.name
[docs] @internal
def getParamType(self, p: HdlIdDef) -> HdlType:
assert p.type in [INT, BOOL, STR], p
return p.type
[docs] @internal
def iterParams(self, unit: Unit):
return unit._ctx.ent.params
[docs] @internal
def iterInterfaces(self, top: Unit):
return top._interfaces
[docs] @internal
def serializeType(self, hdlType: HdlType) -> str:
"""
:see: doc of method on parent class
"""
buff = StringIO()
to_ast = ToHdlAstVhdl2008()
hdl = to_ast.as_hdl_HdlType(hdlType)
ser = ToVhdl2008(buff)
ser.visit_iHdlObj(hdl)
return buff.getvalue()
[docs] @internal
def getVectorFromType(self, dtype) -> Union[bool, None, Tuple[int, int]]:
"""
:see: doc of method on parent class
"""
if dtype == BIT:
return False
elif isinstance(dtype, Bits):
return [dtype.bit_length() - 1, INT.from_py(0)]
[docs] @internal
def getInterfaceType(self, intf: Interface) -> HdlType:
"""
:see: doc of method on parent class
"""
return intf._dtype
[docs] @internal
def getInterfaceLogicalName(self, intf: Interface):
"""
:see: doc of method on parent class
"""
return getSignalName(intf)
[docs] @internal
def getInterfacePhysicalName(self, intf: Interface):
"""
:see: doc of method on parent class
"""
return intf._sigInside.name
[docs] @internal
def getInterfaceDirection(self, thisIntf):
"""
:see: doc of method on parent class
"""
return thisIntf._direction
[docs] @internal
def getTypeWidth(self, dtype: HdlType, do_eval=False)\
-> Tuple[int, Union[int, RtlSignal], bool]:
"""
:see: doc of method on parent class
"""
width = dtype.bit_length()
widthStr = str(width)
return width, widthStr, False
[docs] @internal
def getObjDebugName(self, obj: Union[Interface, Unit, Param]) -> str:
"""
:see: doc of method on parent class
"""
return obj._getFullName()
[docs] @internal
def serialzeValueToTCL(self, val, do_eval=False) -> Tuple[str, str, bool]:
"""
:see: doc of method on parent class
"""
if isinstance(val, int):
val = INT.from_py(val)
if do_eval:
val = val.staticEval()
buff = StringIO()
to_hdl = ToHdlAstVivadoTclExpr()
ser = Vhdl2008Serializer.TO_HDL(buff)
hdl = to_hdl.as_hdl(val)
ser.visit_iHdlObj(hdl)
tclVal = buff.getvalue()
if isinstance(val, RtlSignalBase):
buff = StringIO()
hdl = to_hdl.as_hdl(val.staticEval())
ser = Vhdl2008Serializer.TO_HDL(buff)
ser.visit_iHdlObj(hdl)
tclValVal = buff.getvalue()
return tclVal, tclValVal, False
else:
return tclVal, tclVal, True