Coverage for tsfpga/vivado/generics.py: 97%
38 statements
« prev ^ index » next coverage.py v7.6.12, created at 2025-02-21 20:51 +0000
« prev ^ index » next coverage.py v7.6.12, created at 2025-02-21 20:51 +0000
1# --------------------------------------------------------------------------------------------------
2# Copyright (c) Lukas Vik. All rights reserved.
3#
4# This file is part of the tsfpga project, a project platform for modern FPGA development.
5# https://tsfpga.com
6# https://github.com/tsfpga/tsfpga
7# --------------------------------------------------------------------------------------------------
9from __future__ import annotations
12class StringGenericValue:
13 """
14 Use this type for generic values of type ``string``.
15 """
17 def __init__(self, value: str) -> None:
18 """
19 Arguments:
20 value: A string of variable length with any content.
21 """
22 if not isinstance(value, str):
23 raise TypeError(
24 f"Expected {self.__class__.__name__} value to be of type str."
25 f' Got type="{type(value)}", value="{value}".'
26 )
28 if " " in value:
29 raise ValueError(
30 f'Expected {self.__class__.__name__} value to not contain spaces. Got "{value}".'
31 )
33 self.value = value
35 def __str__(self) -> str:
36 return self.value
39class BitVectorGenericValue:
40 """
41 Use this type for generic values of type ``std_logic_vector``.
42 """
44 def __init__(self, value: str) -> None:
45 """
46 Arguments:
47 value: A string of variable length containing only "1" or "0".
48 """
49 if not isinstance(value, str):
50 raise TypeError(
51 f"Expected {self.__class__.__name__} value to be of type str."
52 f' Got type="{type(value)}", value="{value}".'
53 )
55 for bit_value in value:
56 if bit_value not in ["1", "0"]:
57 raise ValueError(
58 f'Expected {self.__class__.__name__} value to contain only "1" or "0".'
59 f' Got "{value}".'
60 )
62 self.value = value
64 @property
65 def length(self) -> int:
66 """
67 The number of bits in the vector.
68 """
69 return len(self.value)
71 def __str__(self) -> str:
72 return self.value
75def get_vivado_tcl_generic_value(
76 value: bool | float | StringGenericValue | BitVectorGenericValue,
77) -> str:
78 """
79 Convert generic values of different types to the format recognized by Vivado TCL:
80 https://www.xilinx.com/support/answers/52217.html
82 Arguments:
83 value: A generic value of native Python type..
85 Return:
86 The ``value`` formatted as TCL.
87 """
88 # Note that bool is a sub-class of int in Python, so check for bool must be first
89 if isinstance(value, bool):
90 return f"1'b{int(value)}"
92 if isinstance(value, int):
93 return str(value)
95 if isinstance(value, float):
96 return str(value)
98 if isinstance(value, BitVectorGenericValue):
99 return f"{value.length}'b{value.value}"
101 if isinstance(value, StringGenericValue):
102 return f'"{value.value}"'
104 message = f'Unsupported type for generic. Got type="{type(value)}", value="{value}".'
106 # When the type is a string, we can be a little more helpful and indicate what types shall
107 # be used instead.
108 if isinstance(value, str):
109 message += (
110 " Please use either of the explicit types StringGenericValue or BitVectorGenericValue."
111 )
113 raise TypeError(message)