Source code for hwt.hdl.types.structUtils
from copy import copy
from typing import Union, Dict
from hwt.hdl.types.array import HArray
from hwt.hdl.types.bits import Bits
from hwt.hdl.types.enum import HEnum
from hwt.hdl.types.hdlType import HdlType
from hwt.hdl.types.stream import HStream
from hwt.hdl.types.struct import HStructField, HStruct
from hwt.synthesizer.typePath import TypePath
filed_filter_t = Dict[Union[int, str], "filed_filter_t"]
[docs]def HdlType_select(t: HStruct, fieldsToUse: filed_filter_t):
"""
Select fields from type structure (rest will become padding)
:param t: HdlType type instance
:param fieldsToUse: dict {name:{...}} or set of names to select,
dictionary is used to select nested fields
in HStruct/HUnion fields/array items
(f.e. {"struct1": {"field1", "field2"}, "field3":{}}
will select field1 and 2 from struct1 and field3 from root)
"""
template = []
fieldsToUse = fieldsToUse
foundNames = set()
if isinstance(t, (HArray, HStream)):
assert len(fieldsToUse) <= 1, ("select only on item 0, because it has to be same for all array items", fieldsToUse)
k, v = list(fieldsToUse.items())[0]
assert k == 0
new_t = copy(t)
new_t.elment = HdlType_select(t.element_t, v)
return new_t
elif isinstance(t, (Bits, HEnum)):
# scalar
return t
else:
# struct/Union
for f in t.fields:
name = None
subfields = []
if f.name is not None:
try:
if isinstance(fieldsToUse, dict):
subfields = fieldsToUse[f.name]
name = f.name
else:
if f.name in fieldsToUse:
name = f.name
except KeyError:
name = None
if name is not None and subfields:
new_t = HdlType_select(f.dtype, subfields)
template.append(HStructField(new_t, name))
else:
template.append(HStructField(f.dtype, name))
if f.name is not None:
foundNames.add(f.name)
if isinstance(fieldsToUse, dict):
fieldsToUse = set(fieldsToUse.keys())
assert fieldsToUse.issubset(foundNames)
return t.__class__(*template)
[docs]def field_path_get_type(root: HdlType, field_path: TypePath):
"""
Get a data type of element using field path
"""
t = root
for p in field_path:
if isinstance(p, int):
t = t.element_t
else:
assert isinstance(p, str), p
t = t.field_by_name[p].dtype
return t