HAL  v4.5.0-232-g8053ac4b3
The Hardware Analyzer - a comprehensive reverse engineering and manipulation framework for gate-level netlists.
parameter.cpp
Go to the documentation of this file.
2 
3 namespace hal
4 {
6  {
7  py::class_<Parameter> py_parameter(m, "Parameter", R"(
8  A typed, named parameter declaration.
9  )");
10 
11  py::enum_<Parameter::Type>(py_parameter, "Type", R"(
12  Type tag for typed parameters across the netlist.
13  )")
14  .value("Boolean", Parameter::Type::Boolean, R"(A logical boolean (``true`` or ``false``).)")
15  .value("BitVector", Parameter::Type::BitVector, R"(A multi-bit unsigned integer value (2-state).)")
16  .value("LogicVector", Parameter::Type::LogicVector, R"(A multi-bit 9-state logic vector; each bit may be ``0``, ``1``, ``X``, ``Z``, ``U``, ``L``, ``H``, ``W``, or ``-``.)")
17  .value("Integer", Parameter::Type::Integer, R"(A signed 64-bit integer in decimal.)")
18  .value("String", Parameter::Type::String, R"(An arbitrary string.)")
19  .value("Float", Parameter::Type::Float, R"(A double-precision floating-point number.)")
20  .value("Time", Parameter::Type::Time, R"(A time value with a unit suffix (``fs``, ``ps``, ``ns``, ``us``, ``ms``, ``s``, ``min``, ``h``).)")
21  .value("Enum", Parameter::Type::Enum, R"(A finite, ordered set of named values; encoded as an integer index.)");
22 
23  py_parameter.def_static(
24  "Boolean",
25  [](const std::string& name, const std::string& default_value) -> std::optional<Parameter> {
26  auto res = Parameter::Boolean(name, default_value);
27  if (res.is_ok())
28  {
29  return res.get();
30  }
31  else
32  {
33  log_error("python_context", "{}", res.get_error().get());
34  return std::nullopt;
35  }
36  },
37  py::arg("name"),
38  py::arg("default_value"),
39  R"(
40  Construct a boolean parameter. Accepts only the value strings ``"true"`` and ``"false"``.
41 
42  :param str name: Parameter name (must be non-empty).
43  :param str default_value: Default value, either ``"true"`` or ``"false"``.
44  )");
45 
46  py_parameter.def_static(
47  "BitVector",
48  [](const std::string& name, u16 size, const std::string& default_value) -> std::optional<Parameter> {
49  auto res = Parameter::BitVector(name, size, default_value);
50  if (res.is_ok())
51  {
52  return res.get();
53  }
54  else
55  {
56  log_error("python_context", "{}", res.get_error().get());
57  return std::nullopt;
58  }
59  },
60  py::arg("name"),
61  py::arg("size"),
62  py::arg("default_value"),
63  R"(
64  Construct a bit-vector parameter. Values use the prefixes ``0b`` / ``0o`` / ``0x``.
65 
66  :param str name: Parameter name (must be non-empty).
67  :param int size: Bit-width (must be at least 1; up to 65535).
68  :param str default_value: Default value as a string.
69  )");
70 
71  py_parameter.def_static(
72  "LogicVector",
73  [](const std::string& name, u16 size, const std::string& default_value) -> std::optional<Parameter> {
74  auto res = Parameter::LogicVector(name, size, default_value);
75  if (res.is_ok())
76  {
77  return res.get();
78  }
79  else
80  {
81  log_error("python_context", "{}", res.get_error().get());
82  return std::nullopt;
83  }
84  },
85  py::arg("name"),
86  py::arg("size"),
87  py::arg("default_value"),
88  R"(
89  Construct a 9-state logic-vector parameter. Values use the prefixes ``0b`` / ``0o`` / ``0x``,
90  with any of the VHDL ``std_logic`` state characters (``X``, ``Z``, ``U``, ``L``, ``H``, ``W``, ``-``)
91  appearing in place of digits (case-insensitive; for octal/hex, a state-character digit expands to
92  3/4 copies of that state).
93 
94  :param str name: Parameter name (must be non-empty).
95  :param int size: Bit-width (must be at least 1; up to 65535).
96  :param str default_value: Default value as a 9-state literal string (empty for "no default").
97  )");
98 
99  py_parameter.def_static(
100  "Integer",
101  [](const std::string& name, const std::string& default_value) -> std::optional<Parameter> {
102  auto res = Parameter::Integer(name, default_value);
103  if (res.is_ok())
104  {
105  return res.get();
106  }
107  else
108  {
109  log_error("python_context", "{}", res.get_error().get());
110  return std::nullopt;
111  }
112  },
113  py::arg("name"),
114  py::arg("default_value"),
115  R"(
116  Construct a signed-integer parameter. Values are parsed in base 10 and must fit in ``i64``.
117 
118  :param str name: Parameter name (must be non-empty).
119  :param str default_value: Default value as a decimal string (optional leading ``+``/``-``).
120  )");
121 
122  py_parameter.def_static(
123  "String",
124  [](const std::string& name, const std::string& default_value) -> std::optional<Parameter> {
125  auto res = Parameter::String(name, default_value);
126  if (res.is_ok())
127  {
128  return res.get();
129  }
130  else
131  {
132  log_error("python_context", "{}", res.get_error().get());
133  return std::nullopt;
134  }
135  },
136  py::arg("name"),
137  py::arg("default_value"),
138  R"(
139  Construct a string parameter. Any value (including the empty string) is accepted.
140 
141  :param str name: Parameter name (must be non-empty).
142  :param str default_value: Default value.
143  )");
144 
145  py_parameter.def_static(
146  "Float",
147  [](const std::string& name, const std::string& default_value) -> std::optional<Parameter> {
148  auto res = Parameter::Float(name, default_value);
149  if (res.is_ok())
150  {
151  return res.get();
152  }
153  else
154  {
155  log_error("python_context", "{}", res.get_error().get());
156  return std::nullopt;
157  }
158  },
159  py::arg("name"),
160  py::arg("default_value"),
161  R"(
162  Construct a floating-point parameter. Values are parsed via ``std::stod``.
163 
164  :param str name: Parameter name (must be non-empty).
165  :param str default_value: Default value as a decimal float (e.g. ``3.14``, ``1e-5``).
166  )");
167 
168  py_parameter.def_static(
169  "Time",
170  [](const std::string& name, const std::string& default_value) -> std::optional<Parameter> {
171  auto res = Parameter::Time(name, default_value);
172  if (res.is_ok())
173  {
174  return res.get();
175  }
176  else
177  {
178  log_error("python_context", "{}", res.get_error().get());
179  return std::nullopt;
180  }
181  },
182  py::arg("name"),
183  py::arg("default_value"),
184  R"(
185  Construct a time parameter. Values are of the form ``<number><unit>`` with the unit
186  in {``fs``, ``ps``, ``ns``, ``us``, ``ms``, ``s``, ``min``, ``h``}; the number is a
187  non-negative decimal.
188 
189  :param str name: Parameter name (must be non-empty).
190  :param str default_value: Default value, e.g. ``10ns``.
191  )");
192 
193  py_parameter.def_static(
194  "Enum",
195  [](const std::string& name, const std::vector<std::string>& values, const std::string& default_value) -> std::optional<Parameter> {
196  auto res = Parameter::Enum(name, values, default_value);
197  if (res.is_ok())
198  {
199  return res.get();
200  }
201  else
202  {
203  log_error("python_context", "{}", res.get_error().get());
204  return std::nullopt;
205  }
206  },
207  py::arg("name"),
208  py::arg("values"),
209  py::arg("default_value"),
210  R"(
211  Construct an enum parameter. ``size`` is auto-computed as ``ceil(log2(len(values)))``.
212 
213  :param str name: Parameter name (must be non-empty).
214  :param list[str] values: Ordered list of enum values (at least two, unique, non-empty).
215  :param str default_value: Default value, must equal one of `values`.
216  )");
217 
218  py_parameter.def_property_readonly("name", &Parameter::get_name, R"(
219  The name of the parameter (read-only).
220 
221  :type: str
222  )");
223 
224  py_parameter.def("get_name", &Parameter::get_name, R"(
225  Get the name of the parameter.
226 
227  :returns: The parameter name.
228  :rtype: str
229  )");
230 
231  py_parameter.def_property_readonly("type", &Parameter::get_type, R"(
232  The data type of the parameter (read-only).
233 
234  :type: hal_py.Parameter.Type
235  )");
236 
237  py_parameter.def("get_type", &Parameter::get_type, R"(
238  Get the data type of the parameter.
239 
240  :returns: The parameter type.
241  :rtype: hal_py.Parameter.Type
242  )");
243 
244  py_parameter.def_property_readonly("size", &Parameter::get_size, R"(
245  The bit-width of the parameter (read-only).
246  Fixed at 1 for ``Boolean``, 64 for ``Integer`` and ``Float``, 0 for ``String`` and ``Time``,
247  ``ceil(log2(N))`` for ``Enum`` with N values, and the declared width for ``BitVector`` / ``LogicVector``.
248 
249  :type: int
250  )");
251 
252  py_parameter.def("get_size", &Parameter::get_size, R"(
253  Get the bit-width of the parameter.
254  Fixed at 1 for ``Boolean``, 64 for ``Integer`` and ``Float``, 0 for ``String`` and ``Time``,
255  ``ceil(log2(N))`` for ``Enum`` with N values, and the declared width for ``BitVector`` / ``LogicVector``.
256 
257  :returns: The bit-width.
258  :rtype: int
259  )");
260 
261  py_parameter.def_property_readonly("default_value", &Parameter::get_default_value, R"(
262  The default value of the parameter as a string (read-only).
263  An empty string signals "no default"; all other values satisfy the type's grammar.
264 
265  :type: str
266  )");
267 
268  py_parameter.def("get_default_value", &Parameter::get_default_value, R"(
269  Get the default value of the parameter as a string.
270  An empty string signals "no default"; all other values satisfy the type's grammar.
271 
272  :returns: The default value string.
273  :rtype: str
274  )");
275 
276  py_parameter.def_property_readonly("enum_values", &Parameter::get_enum_values, R"(
277  The ordered list of named values for an ``Enum`` parameter (read-only).
278  Always empty for every other type.
279 
280  :type: list[str]
281  )");
282 
283  py_parameter.def("get_enum_values", &Parameter::get_enum_values, R"(
284  Get the ordered list of named values for an ``Enum`` parameter.
285  Always empty for every other type.
286 
287  :returns: The enum value list.
288  :rtype: list[str]
289  )");
290 
291  py_parameter.def("validate", &Parameter::validate, py::arg("value"), R"(
292  Check whether a candidate value is valid for this parameter declaration.
293 
294  Per-type rules:
295 
296  * ``Boolean``: value must be ``"true"`` or ``"false"``.
297  * ``BitVector``: parses as a non-negative integer (``0b``, ``0o``, ``0x``) that fits in ``size``.
298  * ``LogicVector``: parses as a 4-state literal (``0b``, ``0o``, ``0x``) whose total bit-length fits in ``size``.
299  * ``Integer``: parses as a signed decimal integer (fits in ``i64``).
300  * ``String``: any value (including the empty string) is accepted.
301  * ``Float``: parses as a ``double`` via ``std::stod``.
302  * ``Time``: matches ``<number><unit>`` with unit in {``fs``, ``ps``, ``ns``, ``us``, ``ms``, ``s``, ``min``, ``h``}.
303  * ``Enum``: must equal one of the declared enum values.
304 
305  :param str value: The candidate value string.
306  :returns: ``True`` if the value is valid, ``False`` otherwise.
307  :rtype: bool
308  )");
309 
310  py_parameter.def(
311  "encode_as_int",
312  [](Parameter& self, const std::string& value) -> std::optional<u64> {
313  auto res = self.encode_as_int(value);
314  if (res.is_ok())
315  {
316  return res.get();
317  }
318  else
319  {
320  log_error("python_context", "{}", res.get_error().get());
321  return std::nullopt;
322  }
323  },
324  py::arg("value"),
325  R"(
326  Convert a string value to its canonical integer encoding for this parameter.
327 
328  Per-type rules:
329 
330  * ``Boolean``: returns 0 for ``false``, 1 for ``true``.
331  * ``BitVector``: parses the value (``0b``, ``0o``, ``0x``).
332  * ``Integer``: returns the bit-pattern of the signed value reinterpreted as ``u64``.
333  * ``LogicVector``, ``String``, ``Float``, ``Time``: no canonical integer encoding; returns ``None``.
334  * ``Enum``: returns the index of the value in the declared value list.
335 
336  :param str value: The string value to encode.
337  :returns: The integer encoding on success, ``None`` otherwise.
338  :rtype: int or None
339  )");
340 
341  py_parameter.def(py::self == py::self);
342  py_parameter.def(py::self != py::self);
343  }
344 } // namespace hal
u32 size
uint16_t u16
Definition: defines.h:40
void parameter_init(py::module &m)
Definition: parameter.cpp:5
#define log_error(channel,...)
Definition: log.h:78
const Module * module(const Gate *g, const NodeBoxes &boxes)
Definition: defines.h:45
std::string name
static Result< Parameter > Boolean(const std::string &name, const std::string &default_value)
Definition: parameter.cpp:319
static Result< Parameter > BitVector(const std::string &name, u16 size, const std::string &default_value)
Definition: parameter.cpp:340
static Result< Parameter > Integer(const std::string &name, const std::string &default_value)
Definition: parameter.cpp:390
static Result< Parameter > String(const std::string &name, const std::string &default_value)
Definition: parameter.cpp:411
u16 get_size() const
Definition: parameter.cpp:304
static Result< Parameter > LogicVector(const std::string &name, u16 size, const std::string &default_value)
Definition: parameter.cpp:365
Type get_type() const
Definition: parameter.cpp:299
const std::string & get_name() const
Definition: parameter.cpp:294
const std::vector< std::string > & get_enum_values() const
Definition: parameter.cpp:314
static Result< Parameter > Time(const std::string &name, const std::string &default_value)
Definition: parameter.cpp:448
static Result< Parameter > Enum(const std::string &name, const std::vector< std::string > &values, const std::string &default_value)
Definition: parameter.cpp:469
bool validate(const std::string &value) const
Definition: parameter.cpp:505
static Result< Parameter > Float(const std::string &name, const std::string &default_value)
Definition: parameter.cpp:427
const std::string & get_default_value() const
Definition: parameter.cpp:309