Coverage for hdl_registers/bit_vector.py: 100%
54 statements
« prev ^ index » next coverage.py v6.5.0, created at 2023-01-29 22:03 +0000
« prev ^ index » next coverage.py v6.5.0, created at 2023-01-29 22:03 +0000
1# --------------------------------------------------------------------------------------------------
2# Copyright (c) Lukas Vik. All rights reserved.
3#
4# This file is part of the hdl_registers project, a HDL register generator fast enough to be run
5# in real time.
6# https://hdl-registers.com
7# https://gitlab.com/hdl_registers/hdl_registers
8# --------------------------------------------------------------------------------------------------
10# Local folder libraries
11from .register_field import DEFAULT_FIELD_TYPE, RegisterField
12from .register_field_type import FieldType
15class BitVector(RegisterField):
17 """
18 Used to represent a bit vector field in a register.
19 """
21 # pylint: disable=too-many-arguments
22 def __init__(
23 self,
24 name,
25 base_index,
26 description,
27 width,
28 default_value,
29 field_type: FieldType = DEFAULT_FIELD_TYPE,
30 ):
31 """
32 Arguments:
33 name (str): The name of the bit vector.
34 base_index (int): The zero-based index within the register for the lowest bit of this
35 bit vector.
36 description (str): Textual bit vector description.
37 width (int) : The width of the bit vector field.
38 default_value (str): Default value as a string. Must be of length ``width`` and contain
39 only "1" and "0".
40 field_type (FieldType): The field type used to interpret the bits of the field.
41 """
42 self.name = name
43 self._base_index = base_index
44 self.description = description
46 self._check_width(width)
47 self._width = width
49 self._default_value = None
50 # Assign self._default_value via setter
51 self.default_value = default_value
52 self._field_type = field_type
54 @property
55 def field_type(self) -> FieldType:
56 return self._field_type
58 @property
59 def width(self):
60 return self._width
62 def _check_width(self, value):
63 """
64 Sanity checks for the provided width
65 """
66 if not isinstance(value, int):
67 message = (
68 f'Bit vector "{self.name}" should have integer value for "width". Got: "{value}".'
69 )
70 raise ValueError(message)
72 if value < 1 or value > 32:
73 raise ValueError(f'Invalid bit vector width for "{self.name}". Got: "{value}".')
75 @property
76 def base_index(self):
77 """
78 The index within the register for the lowest bit of this Field.
79 """
80 return self._base_index
82 @property
83 def default_value(self):
84 """
85 Getter for default_value.
86 """
87 return self._default_value
89 @default_value.setter
90 def default_value(self, value):
91 """
92 Setter for default_value that performs sanity checks.
93 """
94 if not isinstance(value, str):
95 message = (
96 f'Bit vector "{self.name}" should have string value for "default_value". '
97 f'Got: "{value}"'
98 )
99 raise ValueError(message)
101 if len(value) != self.width:
102 message = (
103 f'Bit vector "{self.name}" should have "default_value" of length {self.width}. '
104 f'Got: "{value}".'
105 )
106 raise ValueError(message)
108 for character in value:
109 if character not in ["0", "1"]:
110 message = (
111 f'Bit vector "{self.name}" invalid binary value for "default_value". '
112 f'Got: "{value}".'
113 )
114 raise ValueError(message)
116 self._default_value = value
118 @property
119 def range(self):
120 return f"{self.base_index + self.width - 1}:{self.base_index}"
122 @property
123 def default_value_str(self):
124 return f"0b{self.default_value}"
126 @property
127 def default_value_uint(self):
128 return int(self.default_value, base=2)
130 def __repr__(self):
131 return f"""{self.__class__.__name__}(\
132name={self.name},\
133base_index={self.base_index},\
134description={self.description},
135width={self.width},\
136default_value={self.default_value},\
137field_type={self.field_type},\
138)"""