Skip to content

Commit 16d3079

Browse files
committed
Merge branch 'vodak-configure-gls-gen' into 'devel'
Configure generator using gls tool See merge request ndk/ndk-fpga!269
2 parents ab8cc38 + 6b7687f commit 16d3079

File tree

2 files changed

+89
-5
lines changed

2 files changed

+89
-5
lines changed

python/ofm/ofm/comp/mfb_tools/debug/gen_loop_switch/gen_loop_switch.py

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -255,17 +255,19 @@ def sm_measure(sm: SpeedMeter, to: float = 0.1, freq: Optional[int] = 2*10**8) -
255255
return sm.measure(to, freq)
256256

257257

258-
def main():
258+
def _main():
259259
help_dict = {
260260
"device" : "set the target device",
261261
"index" : "select index (instance) of the GLS in the Device Tree",
262262
"right" : "select the RIGHT side of the GLS to use the MFB Generator or set loopback",
263263
"left" : "select the LEFT side of the GLS to use the MFB Generator or set loopback",
264264
"loopback" : "enable (1) or disable (0) loopback (on the '-R' or '-L' side)",
265-
"generate" : "start (1) or stop (0) generating (to the '-R' or '-L' side), 'c' to print its config",
265+
"generate" : "start (1) or stop (0) generating (to the '-R' or '-L' side)",
266266
"size" : "set frame size for the ('-R' or '-L') MFB Generator",
267267
"measure" : "measure the throughput using selected Speed Meter (SM), 'a' for all, '0,1' by default",
268268
"config" : "print full configuration and exit",
269+
"gen-config" : "generator config - either print full configuration (no args) or set a value"
270+
" with two extra args"
269271
}
270272

271273
gls_desc = """
@@ -307,10 +309,11 @@ def main():
307309
arg_parser.add_argument("-R", "--right", action="store_true", help=help_dict["right"])
308310
arg_parser.add_argument("-L", "--left", action="store_true", help=help_dict["left"])
309311
arg_parser.add_argument("-l", "--loopback", type=int, choices=[0, 1], help=help_dict["loopback"])
310-
arg_parser.add_argument("-g", "--generate", nargs="?", choices=["0", "1", "c"], help=help_dict["generate"])
312+
arg_parser.add_argument("-g", "--generate", nargs="?", choices=["0", "1"], help=help_dict["generate"])
311313
arg_parser.add_argument("-s", "--size", type=int, help=help_dict["size"])
312314
arg_parser.add_argument("-m", "--measure", nargs='?', const="default", choices=["default", "0", "1", "2", "3", "a"], help=help_dict["measure"])
313315
arg_parser.add_argument("-c", "--config", action="store_true", help=help_dict["config"])
316+
arg_parser.add_argument("-C", "--gen-config", nargs="*", help=help_dict["gen-config"])
314317
args = arg_parser.parse_args()
315318

316319
try:
@@ -377,9 +380,35 @@ def main():
377380
elif "0" in args.generate:
378381
s.gen_stop()
379382

380-
if "c" in args.generate:
383+
if args.gen_config is not None:
384+
if len(args.gen_config) == 0:
381385
print("MFB Generator configuration:")
382386
print(tabulate(s.gen.get_fconfiguration()))
387+
elif len(args.gen_config) == 2:
388+
attr, value = args.gen_config
389+
s.gen.configure_attr(attr, value)
390+
else:
391+
raise ValueError("Invalid number of arguments")
392+
393+
394+
def main():
395+
EXIT_ERROR = 1
396+
397+
try:
398+
_main()
399+
except IndexError as exc:
400+
print("Index error:", exc)
401+
exit(EXIT_ERROR)
402+
except NotImplementedError as exc:
403+
print("Error, feature not yet implemented:", exc)
404+
exit(EXIT_ERROR)
405+
except ValueError as exc:
406+
print("Invalid input:", exc)
407+
print("Maybe a wrong combination of arguments or unknown configuration attribute?")
408+
exit(EXIT_ERROR)
409+
except Exception as exc:
410+
print("Unexpected error: ", exc)
411+
exit(EXIT_ERROR)
383412

384413

385414
if __name__ == "__main__":

python/ofm/ofm/comp/mfb_tools/debug/generator/mfb_generator.py

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,10 @@ class MfbGenerator(nfb.BaseComp):
4848
def __init__(self, *args, **kwargs):
4949
super().__init__(*args, **kwargs)
5050
self._logger = logging.getLogger("MfbGenerator")
51+
self._cfg_type_d = {
52+
f.name : f.type for f in fields(GeneratorConfig)
53+
if "Optional" not in str(f.type) # filter out read only values
54+
}
5155

5256
# ################
5357
# Command register
@@ -222,7 +226,7 @@ def src_mac_address(self, smac: bytes) -> None:
222226

223227
@staticmethod
224228
def convert_bytes2mac(mac: bytes, sep: str = "") -> Any:
225-
"""Conver a 6-byte little-endian MAC address into big-endian with an optional formatting.
229+
"""Convert a 6-byte little-endian MAC address into big-endian with an optional formatting.
226230
227231
Args:
228232
mac: The MAC Address as six little-endian bytes.
@@ -347,6 +351,57 @@ def configure(self, conf: GeneratorConfig) -> None:
347351
self.src_ip_address_mask = conf.src_ip_address_mask
348352
self.enabled = conf.enabled
349353

354+
def _convert_attr(self, attr_name: str, attr_value: str) -> Any:
355+
if "mac" in attr_name:
356+
return MfbGenerator.convert_mac2bytes(attr_value)
357+
358+
if "mask" in attr_name:
359+
return int(attr_value, 16)
360+
361+
prop_type = self._cfg_type_d[attr_name]
362+
return prop_type(attr_value)
363+
364+
def configure_attr(self, attr_name: str, str_value: str):
365+
"""Configure a config attribute.
366+
367+
This method aims to enable dynamic configuration using string names of data class
368+
arguments and string values, that are going to be converted to int/bytes/bool.
369+
For other usages, property setters are recommended.
370+
371+
Args:
372+
attr_name: Attribute name of GeneratorConfig data class.
373+
NOTE that read-only attributes are not allowed.
374+
str_value: Value to be set for given attribute.
375+
376+
Raises:
377+
ValueError: If an invalid attribute name is passed.
378+
AttributeError: If there is an inconsistency between this class's properties and
379+
GeneratorConfig attributes.
380+
IOError: If the given attribute cannot be configured.
381+
"""
382+
383+
if attr_name not in self._cfg_type_d.keys():
384+
attrs_str = ",\n\t".join(self._cfg_type_d.keys())
385+
raise ValueError(
386+
f"Cannot configure {attr_name},"
387+
f" not in supported list of attributes:\n\t{attrs_str}"
388+
)
389+
390+
if attr_name not in dir(self):
391+
raise AttributeError("Internal error!")
392+
393+
if attr_name == "src_ip_address_mask":
394+
version = self._node.get_property("version").value
395+
if version < 2:
396+
raise IOError(
397+
f"Cannot set src_ip_address_mask, version of MFB generator is {version},"
398+
f" but minimal version 2 is required"
399+
)
400+
401+
prop_obj = getattr(type(self), attr_name)
402+
value = self._convert_attr(attr_name, str_value)
403+
prop_obj.fset(self, value)
404+
350405
def get_fconfiguration(self) -> List:
351406
"""Returns formatted configuration of the generator as a list of [item, value] lists."""
352407
conf = self.get_configuration()

0 commit comments

Comments
 (0)