Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1# -------------------------------------------------------------------------------------------------- 

2# Copyright (c) Lukas Vik. All rights reserved. 

3# 

4# This file is part of the tsfpga project. 

5# https://tsfpga.com 

6# https://gitlab.com/tsfpga/tsfpga 

7# -------------------------------------------------------------------------------------------------- 

8 

9from .register_field import RegisterField 

10 

11 

12class BitVector(RegisterField): 

13 

14 """ 

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

16 """ 

17 

18 def __init__(self, name, base_index, description, width, default_value): 

19 """ 

20 Arguments: 

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

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

23 bit vector. 

24 description (str): Textual bit vector description. 

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

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

27 only "1" and "0". 

28 """ 

29 self.name = name 

30 self.base_index = base_index 

31 self.description = description 

32 

33 self._check_width(width) 

34 self._width = width 

35 

36 self._default_value = None 

37 # Assign self._default_value via setter 

38 self.default_value = default_value 

39 

40 @property 

41 def width(self): 

42 return self._width 

43 

44 def _check_width(self, value): 

45 """ 

46 Sanity checks for the provided width 

47 """ 

48 if not isinstance(value, int): 

49 message = ( 

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

51 ) 

52 raise ValueError(message) 

53 

54 if value < 1 or value > 32: 

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

56 

57 @property 

58 def default_value(self): 

59 """ 

60 Getter for default_value. 

61 """ 

62 return self._default_value 

63 

64 @default_value.setter 

65 def default_value(self, value): 

66 """ 

67 Setter for default_value that performs sanity checks. 

68 """ 

69 if not isinstance(value, str): 

70 message = ( 

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

72 f'Got: "{value}"' 

73 ) 

74 raise ValueError(message) 

75 

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

77 message = ( 

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

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

80 ) 

81 raise ValueError(message) 

82 

83 for character in value: 

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

85 message = ( 

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

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

88 ) 

89 raise ValueError(message) 

90 

91 self._default_value = value 

92 

93 def get_value(self, register_value): 

94 shift = self.base_index 

95 mask_at_base = (1 << self.width) - 1 

96 mask = mask_at_base << shift 

97 value = (register_value & mask) >> shift 

98 return value 

99 

100 @property 

101 def range(self): 

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

103 

104 @property 

105 def default_value_str(self): 

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

107 

108 @property 

109 def default_value_uint(self): 

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

111 

112 def __repr__(self): 

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

114name={self.name},\ 

115base_index={self.base_index},\ 

116description={self.description}, 

117width={self.width},\ 

118default_value={self.default_value},\ 

119)"""