Coverage for hdl_registers/generator/vhdl/test/test_register_package.py: 100%

86 statements  

« prev     ^ index     » next       coverage.py v7.6.12, created at 2025-03-12 11:11 +0000

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

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

3# 

4# This file is part of the hdl-registers project, an HDL register generator fast enough to run 

5# in real time. 

6# https://hdl-registers.com 

7# https://github.com/hdl-registers/hdl-registers 

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

9 

10""" 

11Some limited unit tests that check the generated code. 

12Note that the generated VHDL code is also simulated in a functional test. 

13""" 

14 

15import pytest 

16from tsfpga.system_utils import read_file 

17 

18from hdl_registers import HDL_REGISTERS_TESTS 

19from hdl_registers.field.numerical_interpretation import ( 

20 Signed, 

21 SignedFixedPoint, 

22 Unsigned, 

23 UnsignedFixedPoint, 

24) 

25from hdl_registers.generator.vhdl.register_package import VhdlRegisterPackageGenerator 

26from hdl_registers.parser.toml import from_toml 

27from hdl_registers.register_list import RegisterList 

28from hdl_registers.register_modes import REGISTER_MODES 

29 

30 

31def get_package(register_list, output_folder): 

32 return read_file(VhdlRegisterPackageGenerator(register_list, output_folder).create()) 

33 

34 

35class RegisterConfigurationTest: 

36 def __init__(self, name, source_toml_file): 

37 self.register_list = from_toml(name=name, toml_file=source_toml_file) 

38 

39 self.register_list.add_constant(name="boolean_constant", value=True, description="") 

40 self.register_list.add_constant(name="integer_constant", value=3, description="") 

41 self.register_list.add_constant(name="real_constant", value=3.14, description="") 

42 self.register_list.add_constant(name="real_big_constant", value=1e20, description="") 

43 self.register_list.add_constant(name="real_small_constant", value=4e-8, description="") 

44 self.register_list.add_constant(name="string_constant", value="apa", description="") 

45 

46 def test_vhdl_package(self, output_path, test_registers, test_constants): 

47 vhdl = get_package(register_list=self.register_list, output_folder=output_path) 

48 

49 if test_registers: 

50 assert "constant test_register_map : " in vhdl, vhdl 

51 else: 

52 assert "constant test_register_map : " not in vhdl, vhdl 

53 

54 if test_constants: 

55 assert "constant test_constant_boolean_constant : boolean := true;" in vhdl, vhdl 

56 assert "constant test_constant_integer_constant : integer := 3;" in vhdl, vhdl 

57 assert "constant test_constant_real_constant : real := 3.14;" in vhdl, vhdl 

58 assert "constant test_constant_real_big_constant : real := 1.0e+20;" in vhdl, vhdl 

59 assert "constant test_constant_real_small_constant : real := 4.0e-08;" in vhdl, vhdl 

60 assert 'constant test_constant_string_constant : string := "apa";' in vhdl, vhdl 

61 assert ( 

62 "constant test_constant_base_address_hex : " 

63 'unsigned(36 - 1 downto 0) := x"8_0000_0000";' in vhdl 

64 ), vhdl 

65 assert ( 

66 "constant test_constant_base_address_bin : " 

67 'unsigned(36 - 1 downto 0) := "100000000000000000000000000000000000";' in vhdl 

68 ), vhdl 

69 else: 

70 assert "boolean_constant" not in vhdl, vhdl 

71 assert "integer_constant" not in vhdl, vhdl 

72 assert "real_constant" not in vhdl, vhdl 

73 assert "string_constant" not in vhdl, vhdl 

74 

75 

76@pytest.fixture 

77def register_configuration(): 

78 return RegisterConfigurationTest("test", HDL_REGISTERS_TESTS / "regs_test.toml") 

79 

80 

81def test_vhdl_package_with_registers_and_constants(tmp_path, register_configuration): 

82 register_configuration.test_vhdl_package(tmp_path, test_registers=True, test_constants=True) 

83 

84 

85def test_vhdl_package_with_registers_and_no_constants(tmp_path, register_configuration): 

86 register_configuration.register_list.constants = [] 

87 register_configuration.test_vhdl_package(tmp_path, test_registers=True, test_constants=False) 

88 

89 

90def test_vhdl_package_with_constants_and_no_registers(tmp_path, register_configuration): 

91 register_configuration.register_list.register_objects = [] 

92 register_configuration.test_vhdl_package(tmp_path, test_registers=False, test_constants=True) 

93 

94 

95def test_vhdl_package_with_only_one_register(tmp_path): 

96 """ 

97 Test that register_map constant has valid VHDL syntax even when there is only one register. 

98 """ 

99 register_list = RegisterList(name="apa", source_definition_file=None) 

100 register_list.append_register( 

101 name="hest", mode=REGISTER_MODES["r"], description="a single register" 

102 ) 

103 vhdl = read_file(VhdlRegisterPackageGenerator(register_list, tmp_path).create()) 

104 

105 expected = """ 

106 constant apa_register_map : register_definition_vec_t(apa_register_range) := ( 

107 0 => (index => apa_hest, mode => r, utilized_width => 32) 

108 ); 

109 

110 constant apa_regs_init : apa_regs_t := ( 

111 0 => "00000000000000000000000000000000" 

112 ); 

113""" 

114 assert expected in vhdl, vhdl 

115 

116 

117def test_vhdl_typedef(tmp_path): 

118 register_list = RegisterList(name="test", source_definition_file=None) 

119 register = register_list.append_register("number", REGISTER_MODES["r_w"], "") 

120 

121 register.append_bit_vector( 

122 name="u0", 

123 description="", 

124 width=2, 

125 default_value="11", 

126 numerical_interpretation=Unsigned(bit_width=2), 

127 ) 

128 

129 register.append_bit_vector( 

130 name="s0", 

131 description="", 

132 width=2, 

133 default_value="11", 

134 numerical_interpretation=Signed(bit_width=2), 

135 ) 

136 

137 register.append_bit_vector( 

138 name="ufixed0", 

139 description="", 

140 width=2, 

141 default_value="11", 

142 numerical_interpretation=UnsignedFixedPoint(-1, -2), 

143 ) 

144 register.append_bit_vector( 

145 name="ufixed1", 

146 description="", 

147 width=8, 

148 default_value="1" * 8, 

149 numerical_interpretation=UnsignedFixedPoint(5, -2), 

150 ) 

151 

152 register.append_bit_vector( 

153 name="sfixed0", 

154 description="", 

155 width=2, 

156 default_value="11", 

157 numerical_interpretation=SignedFixedPoint(-1, -2), 

158 ) 

159 register.append_bit_vector( 

160 name="sfixed1", 

161 description="", 

162 width=6, 

163 default_value="1" * 6, 

164 numerical_interpretation=SignedFixedPoint(5, 0), 

165 ) 

166 

167 register.append_integer( 

168 name="integer0", description="", min_value=1, max_value=3, default_value=2 

169 ) 

170 

171 vhdl = read_file(VhdlRegisterPackageGenerator(register_list, tmp_path).create()) 

172 

173 assert "subtype test_number_u0_t is u_unsigned(1 downto 0);" in vhdl, vhdl 

174 

175 assert "subtype test_number_s0_t is u_signed(1 downto 0);" in vhdl, vhdl 

176 

177 assert "subtype test_number_ufixed0_t is ufixed(-1 downto -2);" in vhdl, vhdl 

178 assert "subtype test_number_ufixed1_t is ufixed(5 downto -2);" in vhdl, vhdl 

179 

180 assert "subtype test_number_sfixed0_t is sfixed(-1 downto -2);" in vhdl, vhdl 

181 assert "subtype test_number_sfixed1_t is sfixed(5 downto 0);" in vhdl, vhdl 

182 

183 assert "subtype test_number_integer0_t is integer range 1 to 3;" in vhdl, vhdl 

184 

185 

186def test_address_width(tmp_path): 

187 register_list = RegisterList(name="apa", source_definition_file=None) 

188 constant_name = "apa_address_width" 

189 

190 def check(num_addressing_bits): 

191 assert f"{constant_name} : positive := {num_addressing_bits + 2}" in get_package( 

192 register_list, tmp_path 

193 ) 

194 

195 assert constant_name not in get_package(register_list, tmp_path) 

196 

197 register_list.append_register("a", REGISTER_MODES["r"], "") 

198 check(1) 

199 

200 register_list.append_register("b", REGISTER_MODES["r"], "") 

201 check(1) 

202 

203 register_list.append_register("c", REGISTER_MODES["r"], "") 

204 check(2) 

205 

206 register_list.append_register_array("d", 2, "").append_register("e", REGISTER_MODES["r"], "") 

207 check(3)