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 

9import unittest 

10 

11import pytest 

12 

13import tsfpga 

14from tsfpga.system_utils import read_file 

15from tsfpga.registers.parser import from_toml 

16 

17 

18@pytest.mark.usefixtures("fixture_tmp_path") 

19class TestRegisterHtmlGenerator(unittest.TestCase): 

20 tmp_path = None 

21 

22 def setUp(self): 

23 toml_file = tsfpga.TSFPGA_EXAMPLE_MODULES / "artyz7" / "regs_artyz7.toml" 

24 self.registers = from_toml("artyz7", toml_file) 

25 

26 def test_registers(self): 

27 """ 

28 Test that all registers show up in the HTML with correct attributes. 

29 """ 

30 html = self._create_html_page() 

31 

32 self._check_register( 

33 name="plain_dummy_reg", 

34 index=0, 

35 address="0x0000", 

36 mode="Read, Write", 

37 default_value="0xE", 

38 description="A plain <strong>dummy</strong> register.", 

39 html=html, 

40 ) 

41 

42 self._check_register_array( 

43 name="dummy_regs", 

44 length=3, 

45 iterator_range="i &isin; [0, 2]", 

46 description="An <strong>array</strong> with some dummy regs", 

47 html=html, 

48 ) 

49 

50 self._check_register( 

51 name="array_dummy_reg", 

52 index="1 + i &times; 2", 

53 address="0x0004 + i &times; 0x0008", 

54 mode="Read, Write", 

55 default_value="0x31", 

56 description="The first register in the array.", 

57 html=html, 

58 ) 

59 

60 self._check_register( 

61 name="second_array_dummy_reg", 

62 index="2 + i &times; 2", 

63 address="0x0008 + i &times; 0x0008", 

64 mode="Read", 

65 default_value="0x0", 

66 description="The second register in the array.", 

67 html=html, 

68 ) 

69 

70 def test_register_fields(self): 

71 """ 

72 Test that all bits show up in the HTML with correct attributes. 

73 """ 

74 html = self._create_html_page() 

75 

76 # Fields in plain register 

77 self._check_field( 

78 name="plain_bit_a", 

79 index="0", 

80 default_value="0b0", 

81 description="Bit A", 

82 html=html, 

83 ) 

84 self._check_field( 

85 name="plain_bit_b", 

86 index="1", 

87 default_value="0b1", 

88 description="Bit B", 

89 html=html, 

90 ) 

91 self._check_field( 

92 name="plain_bit_vector", 

93 index="5:2", 

94 default_value="0b0011", 

95 description="Bit <strong>vector</strong>", 

96 html=html, 

97 ) 

98 

99 # Fields in register array 

100 self._check_field( 

101 name="array_bit_a", 

102 index="0", 

103 default_value="0b1", 

104 description="Array register bit A", 

105 html=html, 

106 ) 

107 self._check_field( 

108 name="array_bit_b", 

109 index="1", 

110 default_value="0b0", 

111 description="Array register bit B", 

112 html=html, 

113 ) 

114 self._check_field( 

115 name="array_bit_vector", 

116 index="5:2", 

117 default_value="0b1100", 

118 description="Array register bit vector", 

119 html=html, 

120 ) 

121 

122 def test_registers_and_constants(self): 

123 """ 

124 Test that all constant show up in the HTML with correct attributes. 

125 Should only appear if there are actually any constants set. 

126 """ 

127 html = self._create_html_page() 

128 assert "The following constants are part of the register interface" not in html, html 

129 

130 # Add some constants and assert 

131 self.registers.add_constant("data_width", 24) 

132 self.registers.add_constant("decrement", -8) 

133 html = self._create_html_page() 

134 

135 assert "Registers" in html, html 

136 assert "dummy_regs" in html, html 

137 

138 assert "The following constants are part of the register interface" in html, html 

139 self._check_constant(name="data_width", value=24, html=html) 

140 self._check_constant(name="decrement", value=-8, html=html) 

141 

142 def test_constants_and_no_registers(self): 

143 self.registers.register_objects = [] 

144 

145 # Add some constants and assert 

146 self.registers.add_constant("data_width", 24) 

147 self.registers.add_constant("decrement", -8) 

148 html = self._create_html_page() 

149 

150 assert "This module does not have any registers" in html, html 

151 assert "dummy_regs" not in html, html 

152 

153 assert "<h2>Constants</h2>" in html, html 

154 self._check_constant(name="data_width", value=24, html=html) 

155 self._check_constant(name="decrement", value=-8, html=html) 

156 

157 def _create_html_page(self): 

158 self.registers.create_html_page(self.tmp_path) 

159 html = read_file(self.tmp_path / "artyz7_regs.html") 

160 return html 

161 

162 @staticmethod 

163 # pylint: disable=too-many-arguments 

164 def _check_register(name, index, address, mode, default_value, description, html): 

165 expected = f""" 

166 <tr> 

167 <td><strong>{name}</strong></td> 

168 <td>{index}</td> 

169 <td>{address}</td> 

170 <td>{mode}</td> 

171 <td>{default_value}</td> 

172 <td>{description}</td> 

173 </tr> 

174""" 

175 assert expected in html, f"{expected}\n\n{html}" 

176 

177 @staticmethod 

178 def _check_field(name, index, default_value, description, html): 

179 expected = f""" 

180 <tr> 

181 <td>&nbsp;&nbsp;<em>{name}</em></td> 

182 <td>&nbsp;&nbsp;{index}</td> 

183 <td></td> 

184 <td></td> 

185 <td>{default_value}</td> 

186 <td>{description}</td> 

187""" 

188 assert expected in html, f"{expected}\n\n{html}" 

189 

190 @staticmethod 

191 def _check_register_array(name, length, iterator_range, description, html): 

192 expected = f""" 

193 <tr> 

194 <td class="array_header" colspan=5> 

195 Register array <strong>{name}</strong>, repeated {length} times. 

196 Iterator <i>{iterator_range}.</i> 

197 </td> 

198 <td class="array_header">{description}</td> 

199 </tr> 

200""" 

201 assert expected in html, f"{expected}\n\n{html}" 

202 

203 @staticmethod 

204 def _check_constant(name, value, html): 

205 expected = f""" 

206 <tr> 

207 <td><strong>{name}</strong></td> 

208 <td>{value}</td> 

209""" 

210 assert expected in html, f"{expected}\n\n{html}" 

211 

212 def test_register_table_is_empty_string_if_no_registers_are_available(self): 

213 self.registers.register_objects = [] 

214 

215 self.registers.create_html_register_table(self.tmp_path) 

216 html = read_file(self.tmp_path / "artyz7_register_table.html") 

217 assert html == "", html 

218 

219 def test_constant_table_is_empty_string_if_no_constants_are_available(self): 

220 self.registers.constants = [] 

221 

222 self.registers.create_html_constant_table(self.tmp_path) 

223 html = read_file(self.tmp_path / "artyz7_constant_table.html") 

224 assert html == "", html