Coverage for tsfpga/vivado/generics.py: 97%
38 statements
« prev ^ index » next coverage.py v7.6.7, created at 2024-11-20 20:51 +0000
« prev ^ index » next coverage.py v7.6.7, created at 2024-11-20 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# --------------------------------------------------------------------------------------------------
10# Standard libraries
11from typing import Union
14class StringGenericValue:
15 """
16 Use this type for generic values of type ``string``.
17 """
19 def __init__(self, value: str) -> None:
20 """
21 Arguments:
22 value: A string of variable length with any content.
23 """
24 if not isinstance(value, str):
25 raise ValueError(
26 f"Expected {self.__class__.__name__} value to be of type str."
27 f' Got type="{type(value)}", value="{value}".'
28 )
30 if " " in value:
31 raise ValueError(
32 f'Expected {self.__class__.__name__} value to not contain spaces. Got "{value}".'
33 )
35 self.value = value
37 def __str__(self) -> str:
38 return self.value
41class BitVectorGenericValue:
42 """
43 Use this type for generic values of type ``std_logic_vector``.
44 """
46 def __init__(self, value: str) -> None:
47 """
48 Arguments:
49 value: A string of variable length containing only "1" or "0".
50 """
51 if not isinstance(value, str):
52 raise ValueError(
53 f"Expected {self.__class__.__name__} value to be of type str."
54 f' Got type="{type(value)}", value="{value}".'
55 )
57 for bit_value in value:
58 if bit_value not in ["1", "0"]:
59 raise ValueError(
60 f'Expected {self.__class__.__name__} value to contain only "1" or "0".'
61 f' Got "{value}".'
62 )
64 self.value = value
66 @property
67 def length(self) -> int:
68 """
69 The number of bits in the vector.
70 """
71 return len(self.value)
73 def __str__(self) -> str:
74 return self.value
77def get_vivado_tcl_generic_value(
78 value: Union[bool, int, float, StringGenericValue, BitVectorGenericValue]
79) -> str:
80 """
81 Convert generic values of different types to the format recognized by Vivado TCL:
82 https://www.xilinx.com/support/answers/52217.html
84 Arguments:
85 value: A generic value of native Python type..
87 Return:
88 The ``value`` formatted as TCL.
89 """
90 # Note that bool is a sub-class of int in Python, so check for bool must be first
91 if isinstance(value, bool):
92 return f"1'b{int(value)}"
94 if isinstance(value, int):
95 return str(value)
97 if isinstance(value, float):
98 return str(value)
100 if isinstance(value, BitVectorGenericValue):
101 return f"{value.length}'b{value.value}"
103 if isinstance(value, StringGenericValue):
104 return f'"{value.value}"'
106 message = f'Unsupported type for generic. Got type="{type(value)}", value="{value}".'
108 # When the type is a string, we can be a little more helpful and indicate what types shall
109 # be used instead.
110 if isinstance(value, str):
111 message += (
112 " Please use either of the explicit types StringGenericValue or BitVectorGenericValue."
113 )
115 raise ValueError(message)