Coverage for hdl_registers/bit_vector.py: 100%

54 statements  

« prev     ^ index     » next       coverage.py v6.4.4, created at 2022-09-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/tsfpga/hdl_registers 

8# -------------------------------------------------------------------------------------------------- 

9 

10from .register_field import RegisterField, DEFAULT_FIELD_TYPE 

11from .register_field_type import FieldType 

12 

13 

14class BitVector(RegisterField): 

15 

16 """ 

17 Used to represent a bit vector field in a register. 

18 """ 

19 

20 # pylint: disable=too-many-arguments 

21 def __init__( 

22 self, 

23 name, 

24 base_index, 

25 description, 

26 width, 

27 default_value, 

28 field_type: FieldType = DEFAULT_FIELD_TYPE, 

29 ): 

30 """ 

31 Arguments: 

32 name (str): The name of the bit vector. 

33 base_index (int): The zero-based index within the register for the lowest bit of this 

34 bit vector. 

35 description (str): Textual bit vector description. 

36 width (int) : The width of the bit vector field. 

37 default_value (str): Default value as a string. Must be of length ``width`` and contain 

38 only "1" and "0". 

39 field_type (FieldType): The field type used to interpret the bits of the field. 

40 """ 

41 self.name = name 

42 self._base_index = base_index 

43 self.description = description 

44 

45 self._check_width(width) 

46 self._width = width 

47 

48 self._default_value = None 

49 # Assign self._default_value via setter 

50 self.default_value = default_value 

51 self._field_type = field_type 

52 

53 @property 

54 def field_type(self) -> FieldType: 

55 return self._field_type 

56 

57 @property 

58 def width(self): 

59 return self._width 

60 

61 def _check_width(self, value): 

62 """ 

63 Sanity checks for the provided width 

64 """ 

65 if not isinstance(value, int): 

66 message = ( 

67 f'Bit vector "{self.name}" should have integer value for "width". Got: "{value}".' 

68 ) 

69 raise ValueError(message) 

70 

71 if value < 1 or value > 32: 

72 raise ValueError(f'Invalid bit vector width for "{self.name}". Got: "{value}".') 

73 

74 @property 

75 def base_index(self): 

76 """ 

77 The index within the register for the lowest bit of this Field. 

78 """ 

79 return self._base_index 

80 

81 @property 

82 def default_value(self): 

83 """ 

84 Getter for default_value. 

85 """ 

86 return self._default_value 

87 

88 @default_value.setter 

89 def default_value(self, value): 

90 """ 

91 Setter for default_value that performs sanity checks. 

92 """ 

93 if not isinstance(value, str): 

94 message = ( 

95 f'Bit vector "{self.name}" should have string value for "default_value". ' 

96 f'Got: "{value}"' 

97 ) 

98 raise ValueError(message) 

99 

100 if len(value) != self.width: 

101 message = ( 

102 f'Bit vector "{self.name}" should have "default_value" of length {self.width}. ' 

103 f'Got: "{value}".' 

104 ) 

105 raise ValueError(message) 

106 

107 for character in value: 

108 if character not in ["0", "1"]: 

109 message = ( 

110 f'Bit vector "{self.name}" invalid binary value for "default_value". ' 

111 f'Got: "{value}".' 

112 ) 

113 raise ValueError(message) 

114 

115 self._default_value = value 

116 

117 @property 

118 def range(self): 

119 return f"{self.base_index + self.width - 1}:{self.base_index}" 

120 

121 @property 

122 def default_value_str(self): 

123 return f"0b{self.default_value}" 

124 

125 @property 

126 def default_value_uint(self): 

127 return int(self.default_value, base=2) 

128 

129 def __repr__(self): 

130 return f"""{self.__class__.__name__}(\ 

131name={self.name},\ 

132base_index={self.base_index},\ 

133description={self.description}, 

134width={self.width},\ 

135default_value={self.default_value},\ 

136field_type={self.field_type},\ 

137)"""