Coverage for hdl_registers/generator/cpp/cpp_generator_common.py: 97%
106 statements
« prev ^ index » next coverage.py v7.6.9, created at 2024-12-19 20:51 +0000
« prev ^ index » next coverage.py v7.6.9, created at 2024-12-19 20:51 +0000
1# --------------------------------------------------------------------------------------------------
2# Copyright (c) Lukas Vik. All rights reserved.
3#
4# This file is part of the hdl-registers project, an HDL register generator fast enough to run
5# in real time.
6# https://hdl-registers.com
7# https://github.com/hdl-registers/hdl-registers
8# --------------------------------------------------------------------------------------------------
10# Standard libraries
11from pathlib import Path
12from typing import TYPE_CHECKING, Optional
14# First party libraries
15from hdl_registers.field.enumeration import Enumeration
16from hdl_registers.field.integer import Integer
17from hdl_registers.generator.register_code_generator import RegisterCodeGenerator
18from hdl_registers.register_list import RegisterList
20if TYPE_CHECKING:
21 # First party libraries
22 from hdl_registers.field.register_field import RegisterField
23 from hdl_registers.register import Register
24 from hdl_registers.register_array import RegisterArray
27class CppGeneratorCommon(RegisterCodeGenerator):
28 """
29 Class with common methods for generating C++ code.
30 """
32 COMMENT_START = "//"
34 def __init__(self, register_list: RegisterList, output_folder: Path):
35 super().__init__(register_list=register_list, output_folder=output_folder)
37 self._class_name = self.to_pascal_case(snake_string=self.name)
39 @staticmethod
40 def _with_namespace(cpp_code_body: str) -> str:
41 cpp_code = "namespace fpga_regs\n"
42 cpp_code += "{\n\n"
43 cpp_code += f"{cpp_code_body}"
44 cpp_code += "} /* namespace fpga_regs */\n"
45 return cpp_code
47 def _constructor_signature(self) -> str:
48 return (
49 f"{self._class_name}(volatile uint8_t *base_address, "
50 "bool (*assertion_handler) (const std::string*))"
51 )
53 def _get_methods_description(
54 self, register: "Register", register_array: Optional["RegisterArray"]
55 ) -> str:
56 register_description = self.register_description(
57 register=register, register_array=register_array
58 )
59 return f"Methods for the {register_description}."
61 def _field_value_type_name(
62 self,
63 register: "Register",
64 register_array: Optional["RegisterArray"],
65 field: "RegisterField",
66 ) -> str:
67 """
68 The name of the type used to represent the field.
69 """
70 if isinstance(field, Enumeration):
71 # The name of an enum available in this field's attributes.
72 result = f"{self.name}::"
73 if register_array:
74 result += f"{register_array.name}::"
75 result += f"{register.name}::{field.name}::Enumeration"
77 return result
79 if isinstance(field, Integer) and field.is_signed:
80 # Type that can represent negative values also.
81 return "int32_t"
83 # The default for most fields.
84 return "uint32_t"
86 @staticmethod
87 def _register_getter_function_name(
88 register: "Register", register_array: Optional["RegisterArray"]
89 ) -> str:
90 result = "get"
92 if register_array:
93 result += f"_{register_array.name}"
95 result += f"_{register.name}"
97 return result
99 def _register_getter_function_signature(
100 self,
101 register: "Register",
102 register_array: Optional["RegisterArray"],
103 indent: Optional[int] = None,
104 ) -> str:
105 function_name = self._register_getter_function_name(
106 register=register, register_array=register_array
107 )
108 result = f"{function_name}("
110 if register_array:
111 indentation = self.get_indentation(indent=indent)
112 result += f"\n{indentation} size_t array_index\n{indentation}"
114 result += ")"
116 return result
118 @staticmethod
119 def _field_getter_function_name(
120 register: "Register",
121 register_array: Optional["RegisterArray"],
122 field: "RegisterField",
123 from_value: bool,
124 ) -> str:
125 result = "get"
127 if register_array:
128 result += f"_{register_array.name}"
130 result += f"_{register.name}_{field.name}"
132 if from_value:
133 result += "_from_value"
135 return result
137 def _field_getter_function_signature(
138 self,
139 register: "Register",
140 register_array: Optional["RegisterArray"],
141 field: "RegisterField",
142 from_value: bool,
143 indent: Optional[int] = None,
144 ) -> str:
145 indentation = self.get_indentation(indent=indent)
147 function_name = self._field_getter_function_name(
148 register=register, register_array=register_array, field=field, from_value=from_value
149 )
150 result = f"{function_name}("
152 if from_value:
153 # Value is supplied by user
154 result += f"\n{indentation} uint32_t register_value\n{indentation}"
155 elif register_array:
156 # Value shall be read from bus, in which case we need to know array index if this
157 # is an array
158 result += f"\n{indentation} size_t array_index\n{indentation}"
160 result += ")"
162 return result
164 @staticmethod
165 def _register_setter_function_name(
166 register: "Register", register_array: Optional["RegisterArray"]
167 ) -> str:
168 result = "set"
170 if register_array:
171 result += f"_{register_array.name}"
173 result += f"_{register.name}"
175 return result
177 def _register_setter_function_signature(
178 self,
179 register: "Register",
180 register_array: Optional["RegisterArray"],
181 indent: Optional[int] = None,
182 ) -> str:
183 indentation = self.get_indentation(indent=indent)
185 function_name = self._register_setter_function_name(
186 register=register, register_array=register_array
187 )
188 result = f"{function_name}(\n"
190 if register_array:
191 result += f"{indentation} size_t array_index,\n"
193 result += f"{indentation} uint32_t register_value\n{indentation})"
195 return result
197 @staticmethod
198 def _field_setter_function_name(
199 register: "Register",
200 register_array: Optional["RegisterArray"],
201 field: "RegisterField",
202 from_value: bool,
203 ) -> str:
204 result = "set"
206 if register_array:
207 result += f"_{register_array.name}"
209 result += f"_{register.name}_{field.name}"
211 if from_value:
212 result += "_from_value"
214 return result
216 def _field_setter_function_signature(
217 self,
218 register: "Register",
219 register_array: Optional["RegisterArray"],
220 field: "RegisterField",
221 from_value: bool,
222 indent: Optional[int] = None,
223 ) -> str:
224 indentation = self.get_indentation(indent=indent)
226 function_name = self._field_setter_function_name(
227 register=register, register_array=register_array, field=field, from_value=from_value
228 )
229 result = f"{function_name}(\n"
231 if from_value:
232 # Current register value is supplied by user
233 result += f"{indentation} uint32_t register_value,\n"
234 elif register_array:
235 # Current register value shall be read from bus, in which case we need to know array
236 # index if this is an array
237 result += f"{indentation} size_t array_index,\n"
239 type_name = self._field_value_type_name(
240 register=register, register_array=register_array, field=field
241 )
242 result += f"{indentation} {type_name} field_value\n{indentation})"
244 return result