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 .bit import Bit 

10from .bit_vector import BitVector 

11 

12 

13class RegisterMode: 

14 def __init__(self, mode_readable, description): 

15 self.mode_readable = mode_readable 

16 self.description = description 

17 

18 

19REGISTER_MODES = dict( 

20 r=RegisterMode("Read", "Bus can read a value that fabric provides."), 

21 w=RegisterMode("Write", "Bus can write a value that is available for fabric usage."), 

22 r_w=RegisterMode( 

23 "Read, Write", 

24 "Bus can write a value and read it back. The written value is available for fabric usage.", 

25 ), 

26 wpulse=RegisterMode( 

27 "Write-pulse", "Bus can write a value that is asserted for one clock cycle in fabric." 

28 ), 

29 r_wpulse=RegisterMode( 

30 "Read, Write-pulse", 

31 "Bus can read a value that fabric provides. " 

32 "Bus can write a value that is asserted for one clock cycle in fabric.", 

33 ), 

34) 

35 

36 

37class Register: 

38 

39 """ 

40 Used to represent a register and its fields. 

41 """ 

42 

43 def __init__(self, name, index, mode, description): 

44 """ 

45 Arguments: 

46 name (str): The name of the register. 

47 index (int): The zero-based index of this register. 

48 If this register is part of a register array, the index shall be relative to the 

49 start of the array. I.e. the index is zero for the first register in the array. 

50 If the register is a plain register, the index shall be relative to the start of 

51 the register list. 

52 mode (str): A valid register mode. 

53 description (str): Textual register description. 

54 """ 

55 if mode not in REGISTER_MODES: 

56 raise ValueError(f'Invalid mode "{mode}" for register "{name}"') 

57 

58 self.name = name 

59 self.index = index 

60 self.mode = mode 

61 self.description = description 

62 self.fields = [] 

63 self.bit_index = 0 

64 

65 def append_bit(self, name, description, default_value): 

66 """ 

67 Append a bit field to this register. 

68 

69 Arguments: 

70 name (str): The name of the bit. 

71 description (str): Description of the bit. 

72 default_value (str): Default value. Either "1" or "0". 

73 

74 Return: 

75 :class:`.Bit`: The bit object that was created. 

76 """ 

77 bit = Bit( 

78 name=name, index=self.bit_index, description=description, default_value=default_value 

79 ) 

80 self.fields.append(bit) 

81 

82 self.bit_index += bit.width 

83 if self.bit_index > 32: 

84 raise ValueError(f'Maximum width exceeded for register "{self.name}"') 

85 

86 return bit 

87 

88 def append_bit_vector(self, name, description, width, default_value): 

89 """ 

90 Append a bit vector field to this register. 

91 

92 Arguments: 

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

94 width (int) : The width of the bit vector. 

95 description (str): Description of the bit vector. 

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

97 only "1" and "0". 

98 

99 Return: 

100 :class:`.BitVector`: The bit vector object that was created. 

101 """ 

102 bit_vector = BitVector( 

103 name=name, 

104 base_index=self.bit_index, 

105 description=description, 

106 width=width, 

107 default_value=default_value, 

108 ) 

109 self.fields.append(bit_vector) 

110 

111 self.bit_index += bit_vector.width 

112 if self.bit_index > 32: 

113 raise ValueError(f'Maximum width exceeded for register "{self.name}"') 

114 

115 return bit_vector 

116 

117 @property 

118 def default_value(self): 

119 """ 

120 The default value of the register. Depends on the default values of it's fields. 

121 

122 Returns: 

123 int: The default value. 

124 """ 

125 default_value = 0 

126 for field in self.fields: 

127 default_value += field.default_value_uint * 2 ** field.base_index 

128 return default_value 

129 

130 def get_field(self, name): 

131 """ 

132 Get the field within this register that has the given name. Will raise exception if no 

133 field matches. 

134 

135 Arguments: 

136 name (str): The name of the field. 

137 

138 Returns: 

139 :class:`.RegisterField`: The field. 

140 """ 

141 for field in self.fields: 

142 if field.name == name: 

143 return field 

144 

145 raise ValueError(f'Could not find field "{name}" within register "{self.name}"') 

146 

147 @property 

148 def address(self): 

149 """ 

150 int: Byte address, within the register list, of this register. 

151 """ 

152 return 4 * self.index 

153 

154 @property 

155 def is_bus_readable(self): 

156 """ 

157 True if the register is readable by bus. Based on the register type. 

158 """ 

159 return self.mode in ["r", "r_w", "r_wpulse"] 

160 

161 @property 

162 def is_bus_writeable(self): 

163 """ 

164 True if the register is writeable by bus. Based on the register type. 

165 """ 

166 return self.mode in ["w", "r_w", "wpulse", "r_wpulse"] 

167 

168 def __repr__(self): 

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

170name={self.name},\ 

171index={self.index},\ 

172mode={self.mode},\ 

173description={self.description},\ 

174default_value={self.default_value},\ 

175fields={','.join([repr(field) for field in self.fields])},\ 

176)"""