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

56 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. 

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

13""" 

14 

15from tsfpga.system_utils import read_file 

16 

17from hdl_registers.field.numerical_interpretation import ( 

18 Signed, 

19 SignedFixedPoint, 

20 Unsigned, 

21 UnsignedFixedPoint, 

22) 

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

24 VhdlSimulationReadWritePackageGenerator, 

25) 

26from hdl_registers.register_list import RegisterList 

27from hdl_registers.register_modes import REGISTER_MODES 

28 

29 

30def test_package_is_not_generated_without_registers(tmp_path): 

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

32 

33 assert not VhdlSimulationReadWritePackageGenerator(register_list, tmp_path).create().exists() 

34 

35 register_list.add_constant(name="apa", value=True, description="") 

36 assert not VhdlSimulationReadWritePackageGenerator(register_list, tmp_path).create().exists() 

37 

38 register_list.append_register(name="hest", mode=REGISTER_MODES["r_w"], description="") 

39 assert VhdlSimulationReadWritePackageGenerator(register_list, tmp_path).create().exists() 

40 

41 

42def test_re_generating_package_without_registers_should_delete_old_file(tmp_path): 

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

44 register_list.append_register(name="apa", mode=REGISTER_MODES["r_w"], description="") 

45 

46 assert VhdlSimulationReadWritePackageGenerator(register_list, tmp_path).create().exists() 

47 

48 register_list.register_objects = [] 

49 assert not VhdlSimulationReadWritePackageGenerator(register_list, tmp_path).create().exists() 

50 

51 

52def test_read_write_as_integer(tmp_path): 

53 register_list = RegisterList(name="caesar", source_definition_file=None) 

54 

55 register_list.append_register(name="empty", mode=REGISTER_MODES["r_w"], description="") 

56 

57 register = register_list.append_register( 

58 name="full", mode=REGISTER_MODES["r_w"], description="" 

59 ) 

60 register.append_bit(name="my_bit", description="", default_value="0") 

61 register.append_enumeration( 

62 name="my_enumeration", 

63 description="", 

64 elements={"first": "", "second": ""}, 

65 default_value="first", 

66 ) 

67 register.append_integer( 

68 name="my_integer", description="", min_value=0, max_value=127, default_value=0 

69 ) 

70 register.append_bit_vector( 

71 name="my_signed_bit_vector", 

72 description="", 

73 width=4, 

74 default_value="0000", 

75 numerical_interpretation=Signed(bit_width=4), 

76 ) 

77 register.append_bit_vector( 

78 name="my_sfixed_bit_vector", 

79 description="", 

80 width=4, 

81 default_value="0000", 

82 numerical_interpretation=SignedFixedPoint(1, -2), 

83 ) 

84 register.append_bit_vector( 

85 name="my_unsigned_bit_vector", 

86 description="", 

87 width=4, 

88 default_value="0000", 

89 numerical_interpretation=Unsigned(bit_width=4), 

90 ) 

91 register.append_bit_vector( 

92 name="my_ufixed_bit_vector", 

93 description="", 

94 width=4, 

95 default_value="0000", 

96 numerical_interpretation=UnsignedFixedPoint(1, -2), 

97 ) 

98 

99 vhdl = read_file(VhdlSimulationReadWritePackageGenerator(register_list, tmp_path).create()) 

100 

101 def check_access_as_named_type(direction: str, type_name: str, name: str) -> None: 

102 assert direction in ["read", "write"] 

103 in_or_out = "in" if direction == "write" else "out" 

104 expected = f""" 

105 procedure {direction}_caesar_{name}( 

106 signal net : inout network_t; 

107 value : {in_or_out} {type_name}; 

108""" 

109 return expected in vhdl 

110 

111 def check_access_as_integer(direction: str, name: str) -> None: 

112 return check_access_as_named_type(direction=direction, type_name="integer", name=name) 

113 

114 def check_access_as_slv(direction: str, name: str) -> None: 

115 return check_access_as_named_type(direction=direction, type_name="register_t", name=name) 

116 

117 def check_access_as_native(direction: str, name: str) -> None: 

118 return check_access_as_named_type( 

119 direction=direction, type_name=f"caesar_{name}_t", name=name 

120 ) 

121 

122 for direction in ["read", "write"]: 

123 assert check_access_as_integer(direction=direction, name="empty") 

124 assert check_access_as_slv(direction=direction, name="empty") 

125 # Empty register does not have a native record type. 

126 assert not check_access_as_native(direction=direction, name="empty") 

127 

128 assert check_access_as_integer(direction=direction, name="full") 

129 # Register with fields does not have a write as SLV function. 

130 assert check_access_as_slv(direction=direction, name="full") == (direction == "read") 

131 assert check_access_as_native(direction=direction, name="full") 

132 

133 # Only non-fractional vector types shall have the possibility of accessing as integer. 

134 assert check_access_as_integer(direction=direction, name="full_my_signed_bit_vector") 

135 assert check_access_as_native(direction=direction, name="full_my_signed_bit_vector") 

136 assert check_access_as_integer(direction=direction, name="full_my_unsigned_bit_vector") 

137 assert not check_access_as_integer(direction=direction, name="full_my_ufixed_bit_vector") 

138 assert not check_access_as_integer(direction=direction, name="full_my_sfixed_bit_vector") 

139 assert not check_access_as_integer(direction=direction, name="full_my_bit") 

140 assert not check_access_as_integer(direction=direction, name="full_my_enumeration") 

141 assert not check_access_as_integer(direction=direction, name="full_my_integer")