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

88 statements  

« prev     ^ index     » next       coverage.py v7.6.10, created at 2025-01-28 20:51 +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 

15# Standard libraries 

16from pathlib import Path 

17 

18# Third party libraries 

19from tsfpga.system_utils import read_file 

20 

21# First party libraries 

22from hdl_registers.generator.vhdl.axi_lite.wrapper import VhdlAxiLiteWrapperGenerator 

23from hdl_registers.generator.vhdl.record_package import VhdlRecordPackageGenerator 

24from hdl_registers.generator.vhdl.register_package import VhdlRegisterPackageGenerator 

25from hdl_registers.generator.vhdl.simulation.check_package import ( 

26 VhdlSimulationCheckPackageGenerator, 

27) 

28from hdl_registers.generator.vhdl.simulation.read_write_package import ( 

29 VhdlSimulationReadWritePackageGenerator, 

30) 

31from hdl_registers.generator.vhdl.simulation.wait_until_package import ( 

32 VhdlSimulationWaitUntilPackageGenerator, 

33) 

34from hdl_registers.register_list import RegisterList 

35from hdl_registers.register_modes import REGISTER_MODES 

36 

37 

38def generate_all_vhdl_artifacts(register_list: RegisterList, output_folder: Path) -> None: 

39 VhdlRegisterPackageGenerator( 

40 register_list=register_list, output_folder=output_folder 

41 ).create_if_needed() 

42 

43 VhdlRecordPackageGenerator( 

44 register_list=register_list, output_folder=output_folder 

45 ).create_if_needed() 

46 

47 VhdlAxiLiteWrapperGenerator( 

48 register_list=register_list, output_folder=output_folder 

49 ).create_if_needed() 

50 

51 VhdlSimulationReadWritePackageGenerator( 

52 register_list=register_list, output_folder=output_folder 

53 ).create_if_needed() 

54 

55 VhdlSimulationCheckPackageGenerator( 

56 register_list=register_list, output_folder=output_folder 

57 ).create_if_needed() 

58 

59 VhdlSimulationWaitUntilPackageGenerator( 

60 register_list=register_list, output_folder=output_folder 

61 ).create_if_needed() 

62 

63 

64def generate_strange_register_maps(output_path): 

65 """ 

66 Generate register VHDL artifacts for some strange niche cases. 

67 """ 

68 

69 def create_packages(direction, mode): 

70 def append_register(data, name): 

71 """ 

72 Append a register with some fields. 

73 """ 

74 register = data.append_register( 

75 name=f"{name}_{mode.shorthand}", mode=mode, description="" 

76 ) 

77 

78 register.append_integer( 

79 name="integer", description="", min_value=-10, max_value=10, default_value=3 

80 ) 

81 register.append_enumeration( 

82 name="enumeration", description="", elements=dict(a="", b=""), default_value="b" 

83 ) 

84 

85 def append_registers(data): 

86 """ 

87 Append some registers with some fields, either to a RegisterList or a RegisterArray. 

88 """ 

89 append_register(data=data, name="first") 

90 append_register(data=data, name="second") 

91 

92 # Some plain registers, in one direction only. 

93 register_list = RegisterList(name=f"plain_only_{direction}") 

94 append_registers(data=register_list) 

95 generate_all_vhdl_artifacts(register_list=register_list, output_folder=output_path) 

96 

97 # Some register arrays, in one direction only. 

98 register_list = RegisterList(name=f"array_only_{direction}") 

99 register_array = register_list.append_register_array(name="apa", length=5, description="") 

100 append_registers(data=register_array) 

101 register_array = register_list.append_register_array(name="hest", length=10, description="") 

102 append_registers(data=register_array) 

103 generate_all_vhdl_artifacts(register_list=register_list, output_folder=output_path) 

104 

105 # Plain registers and some register arrays, in one direction only. 

106 register_list = RegisterList(name=f"plain_and_array_only_{direction}") 

107 append_registers(data=register_list) 

108 register_array = register_list.append_register_array(name="apa", length=5, description="") 

109 append_registers(data=register_array) 

110 register_array = register_list.append_register_array(name="hest", length=10, description="") 

111 append_registers(data=register_array) 

112 generate_all_vhdl_artifacts(register_list=register_list, output_folder=output_path) 

113 

114 # Mode 'Read only' should give registers only in the 'up' direction' 

115 create_packages(direction="up", mode=REGISTER_MODES["r"]) 

116 # Mode 'Write only' should give registers only in the 'down' direction' 

117 create_packages(direction="down", mode=REGISTER_MODES["w"]) 

118 

119 register_list = RegisterList(name="only_constants") 

120 register_list.add_constant(name="first", value=123, description="") 

121 register_list.add_constant(name="second", value=True, description="") 

122 register_list.add_constant(name="third", value=5e30, description="") 

123 register_list.add_constant(name="fourth", value=1e-12, description="") 

124 generate_all_vhdl_artifacts(register_list=register_list, output_folder=output_path) 

125 

126 register_list = RegisterList(name="empty") 

127 generate_all_vhdl_artifacts(register_list=register_list, output_folder=output_path) 

128 

129 

130def _get_register_arrays_record_string(direction): 

131 return ( 

132 f"records for the registers of each register array the are in the '{direction}' direction" 

133 ) 

134 

135 

136def test_registers_only_in_up_direction_should_give_no_down_type_or_port(tmp_path): 

137 generate_strange_register_maps(output_path=tmp_path) 

138 

139 for file_name in ["array_only_up", "plain_and_array_only_up", "plain_only_up"]: 

140 vhd = read_file(tmp_path / f"{file_name}_register_record_pkg.vhd") 

141 

142 assert f"{file_name}_regs_up_t" in vhd 

143 assert f"{file_name}_regs_down_t" not in vhd 

144 

145 # If there are no arrays there should be no records for arrays, and this comment shall not 

146 # be present. 

147 string = _get_register_arrays_record_string("up") 

148 if "array" in file_name: 

149 assert string in vhd 

150 else: 

151 assert string not in vhd 

152 

153 # The 'down' comment shall never be present since we have no 'down' registers. 

154 string = _get_register_arrays_record_string("down") 

155 assert string not in vhd 

156 

157 vhd = read_file(tmp_path / f"{file_name}_register_file_axi_lite.vhd") 

158 

159 assert "regs_up : in" in vhd 

160 assert "regs_down : out" not in vhd 

161 

162 assert "reg_was_read : out" in vhd 

163 assert "reg_was_written : out" not in vhd 

164 

165 

166def test_registers_only_in_down_direction_should_give_no_down_type_or_port(tmp_path): 

167 generate_strange_register_maps(output_path=tmp_path) 

168 

169 for file_name in ["array_only_down", "plain_and_array_only_down", "plain_only_down"]: 

170 vhd = read_file(tmp_path / f"{file_name}_register_record_pkg.vhd") 

171 

172 assert f"{file_name}_regs_up_t" not in vhd 

173 assert f"{file_name}_regs_down_t" in vhd 

174 

175 # If there are no arrays there should be no records for arrays, and this comment shall not 

176 # be present. 

177 string = _get_register_arrays_record_string("down") 

178 if "array" in file_name: 

179 assert string in vhd 

180 else: 

181 assert string not in vhd 

182 

183 # The 'up' comment shall never be present since we have no 'up' registers. 

184 string = _get_register_arrays_record_string("up") 

185 assert string not in vhd 

186 

187 vhd = read_file(tmp_path / f"{file_name}_register_file_axi_lite.vhd") 

188 

189 assert "regs_up : in" not in vhd 

190 assert "regs_down : out" in vhd 

191 

192 assert "reg_was_read : out" not in vhd 

193 assert "reg_was_written : out" in vhd