rtl-buddy 2.1.4__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
rtl_buddy/__init__.py ADDED
@@ -0,0 +1,5 @@
1
+ # rtl-buddy
2
+ # vim: set sw=2:ts=2:et:
3
+ #
4
+ # Copyright 2024 rtl_buddy contributors
5
+ #
rtl_buddy/__main__.py ADDED
@@ -0,0 +1,18 @@
1
+ # rtl-buddy
2
+ # vim: set sw=2:ts=2:et:
3
+ #
4
+ # Copyright 2024 rtl_buddy contributors
5
+ #
6
+ import logging
7
+ from .rtl_buddy import RtlBuddy
8
+
9
+ DESCRIPTION = """
10
+ RTL Buddy is a RTL development build system.
11
+ """
12
+
13
+ def main() -> int:
14
+ rb = RtlBuddy(name='rtl_buddy_inst')
15
+ return rb.run()
16
+
17
+ if __name__ == '__main__':
18
+ raise SystemExit(main())
@@ -0,0 +1,17 @@
1
+ # rtl-buddy
2
+ # vim: set sw=2:ts=2:et:
3
+ #
4
+ # Copyright 2024 rtl_buddy contributors
5
+ #
6
+
7
+ # Re-export config classes
8
+ from .test import TestConfig, TestbenchConfig
9
+ from .suite import SuiteConfig
10
+ from .reg import RegConfig
11
+ from .root import RootConfig
12
+ from .platform import PlatformConfig
13
+ from .rtl import RtlBuilderConfig
14
+ from .model import ModelConfig, ModelConfigLoader
15
+ from .verible import VeribleConfig
16
+ from .coverage import CoverageConfig, CoverageConfigFile
17
+ from .coverview import CoverviewConfig, CoverviewConfigFile
@@ -0,0 +1,41 @@
1
+ import pprint
2
+
3
+ from dataclasses import dataclass
4
+ from serde import serde, field
5
+
6
+
7
+ @dataclass
8
+ class CoverageConfig:
9
+ """
10
+ Coverage post-processing configuration for a simulator family.
11
+
12
+ Attributes:
13
+ name (str): Simulator family name, e.g. "verilator" or "vcs".
14
+ use_lcov (bool): Whether LCOV output should be emitted for this simulator.
15
+ """
16
+ name: str
17
+ use_lcov: bool
18
+
19
+ def get_name(self) -> str:
20
+ return self.name
21
+
22
+ def get_use_lcov(self) -> bool:
23
+ return self.use_lcov
24
+
25
+ def __str__(self):
26
+ return pprint.pformat(self)
27
+
28
+
29
+ @serde
30
+ class CoverageConfigFile:
31
+ """
32
+ YAML-backed coverage configuration entry.
33
+ """
34
+ name: str
35
+ use_lcov: bool = field(rename='use-lcov', default=False)
36
+
37
+ def initialise(self) -> CoverageConfig:
38
+ return CoverageConfig(
39
+ name=self.name,
40
+ use_lcov=self.use_lcov,
41
+ )
@@ -0,0 +1,54 @@
1
+ import pprint
2
+ from collections.abc import Mapping
3
+
4
+ from dataclasses import dataclass
5
+ from serde import serde, field
6
+
7
+
8
+ @dataclass
9
+ class CoverviewConfig:
10
+ """
11
+ Coverview packaging configuration for a simulator family.
12
+
13
+ Attributes:
14
+ name (str): Simulator family name, e.g. "verilator" or "vcs".
15
+ config (dict): Inline Coverview JSON-compatible configuration values.
16
+ generate_tables (str | None): Optional coverage type to use for Coverview tables.
17
+ """
18
+ name: str
19
+ config: dict
20
+ generate_tables: str | None
21
+
22
+ def get_name(self) -> str:
23
+ return self.name
24
+
25
+ def get_config(self) -> dict:
26
+ return self.config
27
+
28
+ def get_generate_tables(self) -> str | None:
29
+ return self.generate_tables
30
+
31
+ def __str__(self):
32
+ return pprint.pformat(self)
33
+
34
+
35
+ @serde
36
+ class CoverviewConfigFile:
37
+ """
38
+ YAML-backed Coverview packaging configuration entry.
39
+ """
40
+ name: str
41
+ config: dict = field(default_factory=dict)
42
+ generate_tables: str | None = field(rename='generate-tables', default=None)
43
+
44
+ def initialise(self, root_cfg_path: str) -> CoverviewConfig:
45
+ del root_cfg_path
46
+ if not isinstance(self.config, Mapping):
47
+ raise ValueError(
48
+ f"cfg-coverview '{self.name}' config must be a mapping of inline Coverview JSON values"
49
+ )
50
+ return CoverviewConfig(
51
+ name=self.name,
52
+ config=dict(self.config),
53
+ generate_tables=self.generate_tables,
54
+ )
@@ -0,0 +1,106 @@
1
+ import logging
2
+ logger = logging.getLogger(__name__)
3
+ import pprint
4
+
5
+ from serde import serde, field
6
+ from serde.yaml import from_yaml
7
+ from typing import Literal
8
+
9
+ from ..errors import FatalRtlBuddyError
10
+ from ..logging_utils import log_event
11
+
12
+ @serde
13
+ class ModelConfig:
14
+ """
15
+ Representation of a single model entry in a 'model_config' file
16
+
17
+ Attributes
18
+ name (str): Unique model identifier.
19
+ filelist (list[str]): List of paths to files associated with the model.
20
+ path (str|None): Path to the model config file. Will usually be set by the loader.
21
+ """
22
+ name: str
23
+ filelist: list[str]
24
+ path: str|None
25
+
26
+ def get_model_name(self):
27
+ """
28
+ Retrieve the value of model_name.
29
+
30
+ Returns:
31
+ model_name (str): The value of model_name in the model.
32
+ """
33
+ return self.model_name
34
+
35
+ def get_model_path(self):
36
+ """
37
+ Retrieve the value of path.
38
+
39
+ Returns:
40
+ path (str): The value of path in the model. The path to the model config file.
41
+ """
42
+ return self.path
43
+
44
+ def get_filelist(self):
45
+ """
46
+ Retrieve the value of filelist.
47
+
48
+ Returns:
49
+ filelist (list[str]): The value of filelist in the model.
50
+ """
51
+ return self.filelist
52
+
53
+ def __str__(self):
54
+ return pprint.pformat(self)
55
+
56
+ @serde
57
+ class ModelConfigFile:
58
+ """
59
+ Representation of a 'model_config' file.
60
+
61
+ Attributes
62
+ rtl_buddy_filetype (Literal['model_config']): Config file type. Must be 'model_config'.
63
+ models (list[RawModelConfig]): List of model configurations.
64
+ """
65
+ rtl_buddy_filetype: Literal['model_config'] = field(rename='rtl-buddy-filetype')
66
+ models: list[ModelConfig] = field(default_factory=list)
67
+
68
+ # TODO: Raise errors instead of killing things here
69
+ class ModelConfigLoader:
70
+ """
71
+ Helper class to load model configurations from a file. Reads the file once.
72
+
73
+ Attributes:
74
+ models(list[RawModelConfig]): List of raw model configs.
75
+ """
76
+ def __init__(self, path:str) -> None:
77
+ self.path = path
78
+ self.models = []
79
+
80
+ try:
81
+ with open(self.path, 'r') as file:
82
+ data = from_yaml(ModelConfigFile, file.read())
83
+ self.models = data.models
84
+ except Exception as e:
85
+ log_event(logger, logging.ERROR, "model_config.load_failed", path=path, error=e)
86
+ raise FatalRtlBuddyError(f'failed to load "{path}"') from e
87
+
88
+ def get_model(self, model_name:str) -> ModelConfig:
89
+ """
90
+ Get a ModelConfig according to model_name.
91
+
92
+ Args:
93
+ name (str): Unique system identifier for the model.
94
+ model_name (str): Unique identifier for the model in file.
95
+ Returns:
96
+ model (ModelConfig): The model configuration.
97
+ Raises:
98
+ Panics if no model corresponding to model_name can be found.
99
+ """
100
+ for model in self.models:
101
+ if model.name == model_name:
102
+ model.path = self.path
103
+ return model
104
+
105
+ log_event(logger, logging.ERROR, "model_config.model_not_found", model=model_name, path=self.path)
106
+ raise FatalRtlBuddyError(f"model '{model_name}' not found")
@@ -0,0 +1,108 @@
1
+ import logging
2
+ logger = logging.getLogger(__name__)
3
+ import pprint
4
+
5
+ from dataclasses import dataclass
6
+ from serde import serde, field
7
+ from .rtl import RtlBuilderConfig
8
+ from .verible import VeribleConfig
9
+ from ..errors import FatalRtlBuddyError
10
+ from ..logging_utils import log_event
11
+
12
+ @dataclass
13
+ class PlatformConfig:
14
+ """
15
+ Configuration entry defining a single test platoform.
16
+
17
+ Attributes:
18
+ os (str): Target OS of platform.
19
+ unames (list[str]): List of supported unames for the platform.
20
+ builder (str | None): Name of builder configuration associated with the platform.
21
+ verible (str): Name of verible configuration associated with the platform.
22
+ """
23
+ os: str
24
+ unames: list[str]
25
+ builder: RtlBuilderConfig
26
+ verible: VeribleConfig
27
+
28
+ def get_os(self) -> str:
29
+ """
30
+ Retrieve the value of os.
31
+
32
+ Returns:
33
+ os (str): The value of os
34
+ """
35
+ return self.os
36
+
37
+ def get_builder(self) -> RtlBuilderConfig:
38
+ """
39
+ Get the value of builder
40
+
41
+ Returns:
42
+ builder (RtlBuilderConfig): The value of builder.
43
+ """
44
+ return self.builder
45
+
46
+ def get_verible(self) -> VeribleConfig:
47
+ """
48
+ Get the value of verible.
49
+
50
+ Returns:
51
+ verible_name (str): The value of verible.
52
+ """
53
+ return self.verible
54
+
55
+ def __str__(self) -> str:
56
+ return pprint.pformat(self)
57
+
58
+ @serde
59
+ class PlatformConfigFile:
60
+ os: str
61
+ unames: list[str]
62
+ builder: str | None
63
+ verible: str
64
+
65
+ def initialise(self, builders:dict[str, RtlBuilderConfig], veribles:dict[str, VeribleConfig], builder_override:str|None) -> PlatformConfig:
66
+ builder = None
67
+ if self.builder is not None:
68
+ if self.builder not in builders:
69
+ log_event(logger, logging.ERROR, "platform.builder_missing", builder=self.builder, os=self.os)
70
+ raise FatalRtlBuddyError(f'"{self.builder}" not in root config')
71
+
72
+ builder = builders[self.builder]
73
+
74
+ if builder_override is not None:
75
+ log_event(logger, logging.INFO, "platform.builder_override", builder=builder_override, configured_builder=self.builder, os=self.os)
76
+ if builder_override not in builders:
77
+ log_event(logger, logging.ERROR, "platform.builder_override_missing", builder=builder_override, os=self.os)
78
+ raise FatalRtlBuddyError(f'Builder override "{builder_override}" is not in root config.')
79
+
80
+ builder = builders[builder_override]
81
+
82
+ if builder is None:
83
+ log_event(logger, logging.ERROR, "platform.builder_unset", os=self.os)
84
+ raise FatalRtlBuddyError("Both builder and builder_override are not set. Builder is None")
85
+
86
+ if self.verible not in veribles:
87
+ log_event(logger, logging.ERROR, "platform.verible_missing", verible=self.verible, os=self.os)
88
+ raise FatalRtlBuddyError(f'"{self.verible}" not in verible config')
89
+
90
+ return PlatformConfig(self.os, self.unames, builder, veribles[self.verible])
91
+
92
+ def get_os(self) -> str:
93
+ """
94
+ Retrieve the value of os.
95
+
96
+ Returns:
97
+ os (str): The value of os
98
+ """
99
+ return self.os
100
+
101
+ def get_unames(self) -> list[str]:
102
+ """
103
+ Retrieve the value of unames, the list of unames supported by the platform.
104
+
105
+ Returns:
106
+ unames (list[str]): The value of unames.
107
+ """
108
+ return self.unames
@@ -0,0 +1,84 @@
1
+ import logging
2
+ logger = logging.getLogger(__name__)
3
+ import pprint
4
+ import os
5
+
6
+ from serde import serde, field, SerdeError
7
+ from serde.yaml import from_yaml
8
+ from typing import Literal
9
+ from .suite import SuiteConfig
10
+ from ..errors import FatalRtlBuddyError
11
+ from ..logging_utils import log_event
12
+
13
+ @serde
14
+ class RegConfigFile:
15
+ """
16
+ Representation of a "reg_config' file.
17
+
18
+ Attributes
19
+ rtl_buddy_filetype (Literal['reg_config']): Config file type. Must be 'reg_config'.
20
+ test_configs (list[str]): List of paths to test configurations.
21
+ """
22
+ rtl_buddy_filetype: Literal['reg_config'] = field(rename='rtl-buddy-filetype')
23
+ test_configs: list[str] = field(rename='test-configs', default_factory=list)
24
+
25
+ class RegConfig:
26
+ """
27
+ Configuration for a set of regression tests.
28
+
29
+ Attributes:
30
+ name (str): Unique regression test identifier.
31
+ path (str): Path to the regression test file.
32
+ test_configs (list[str]): List of paths to test suite files defining tests in the regression test.
33
+ """
34
+
35
+ def __init__(self, name:str, path:str) -> None:
36
+ """
37
+ Initialise a RegConfig given a path to a YAML configuration file.
38
+
39
+ Args:
40
+ name (str): Unique regression test identifier.
41
+ path (str): Path to the regression test configuration file.
42
+ Raises:
43
+ SystemExitError: If there was an error parsing the file.
44
+ """
45
+ self.name = name
46
+ self.path = path
47
+ self.suite_configs = []
48
+ try:
49
+ with open(path, 'r') as file:
50
+ data = from_yaml(RegConfigFile, file.read())
51
+ self.suite_configs = list(map(lambda suite_path: SuiteConfig(os.path.join(os.path.dirname(self.path), suite_path)), data.test_configs))
52
+ except Exception as e:
53
+ log_event(logger, logging.ERROR, "regression_config.load_failed", name=self.name, path=path, error=e)
54
+ raise FatalRtlBuddyError(f'{self.name}: failed to load "{path}"') from e
55
+
56
+ def get_name(self):
57
+ """
58
+ Retrieve the value of name
59
+
60
+ Returns:
61
+ name (str): The name of the regression test
62
+ """
63
+ return self.name
64
+
65
+ def get_path(self):
66
+ """
67
+ Retrieve the value of path
68
+
69
+ Returns
70
+ path (str): The value of path in the regression test
71
+ """
72
+ return self.path
73
+
74
+ def get_suite_configs(self):
75
+ """
76
+ Retrieve the value of suite_configs
77
+
78
+ Returns
79
+ test_configs (list[SuiteConfig]): The value of suite_configs in the regression test
80
+ """
81
+ return self.suite_configs
82
+
83
+ def __str__(self):
84
+ return pprint.pformat(self)