Coverage for hdl_registers/generator/vhdl/simulation/vhdl_simulation_generator_common.py: 94%

36 statements  

« prev     ^ index     » next       coverage.py v7.6.12, created at 2025-02-15 20:50 +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 

10from __future__ import annotations 

11 

12from typing import TYPE_CHECKING 

13 

14from hdl_registers.generator.vhdl.vhdl_generator_common import VhdlGeneratorCommon 

15 

16if TYPE_CHECKING: 

17 from hdl_registers.register import Register 

18 from hdl_registers.register_array import RegisterArray 

19 

20 

21class VhdlSimulationGeneratorCommon(VhdlGeneratorCommon): 

22 """ 

23 Common methods for generation of VHDL simulation code. 

24 """ 

25 

26 def get_array_index_port(self, register_array: RegisterArray | None) -> str: 

27 """ 

28 Get the array index port declaration. 

29 Suitable for VHDL procedure/function signatures that can read registers in arrays. 

30 """ 

31 if register_array: 

32 array_name = self.qualified_register_array_name(register_array=register_array) 

33 return f" array_index : in {array_name}_range;\n" 

34 

35 return "" 

36 

37 @staticmethod 

38 def get_array_index_association(register_array: RegisterArray | None) -> str: 

39 """ 

40 Get the array index association. 

41 Suitable when associating the array index port to a read/write procedure call. 

42 """ 

43 if register_array: 

44 return " array_index => array_index,\n" 

45 

46 return "" 

47 

48 def reg_index_constant( 

49 self, register: Register, register_array: RegisterArray | None = None 

50 ) -> str: 

51 """ 

52 Get a 'reg_index' constant declaration, for the index of the supplied register. 

53 If the register is in an array, the constant calculation depends on a 'array_index' 

54 being present in the VHDL. 

55 

56 Is suitable for implementation of register/field access procedures. 

57 """ 

58 register_name = self.qualified_register_name( 

59 register=register, register_array=register_array 

60 ) 

61 reg_index = ( 

62 f"{register_name}(array_index=>array_index)" if register_array else register_name 

63 ) 

64 

65 return f" constant reg_index : {self.name}_register_range := {reg_index};\n" 

66 

67 @staticmethod 

68 def reg_address_constant() -> str: 

69 """ 

70 Get a 'reg_address' constant declaration, for the byte address of the current register. 

71 Depends on the 'reg_index' and 'base_address' constants being present in the VHDL. 

72 

73 Is suitable for implementation of register/field access procedures. 

74 """ 

75 return ( 

76 " constant reg_address : addr_t := base_address + " 

77 "to_unsigned(4 * reg_index, addr_width);\n" 

78 ) 

79 

80 @staticmethod 

81 def get_register_array_message(register_array: RegisterArray | None) -> str: 

82 """ 

83 Status message for register array information. 

84 Suitable for error printouts. 

85 

86 If the register we are working on is in a register array, the 'array_index' value must 

87 be available as an integer in VHDL. 

88 """ 

89 if register_array: 

90 register_array_message = ( 

91 f" within the '{register_array.name}[" 

92 '" & to_string(array_index) & "]\' register array' 

93 ) 

94 else: 

95 register_array_message = "" 

96 

97 return f"""\ 

98 constant register_array_message : string := "{register_array_message}"; 

99""" 

100 

101 @staticmethod 

102 def get_base_address_message() -> str: 

103 """ 

104 Status message for base address information. 

105 Suitable for error printouts. 

106 

107 Depends on a 'base_address' value being available as an 'unsigned' in VHDL. 

108 """ 

109 return """\ 

110 function base_address_message return string is 

111 begin 

112 if base_address /= 0 then 

113 return " (at base address " & hex_image(std_logic_vector(base_address)) & ")"; 

114 end if; 

115 

116 return ""; 

117 end function; 

118""" 

119 

120 @staticmethod 

121 def get_message() -> str: 

122 """ 

123 Get the compounded status message. 

124 Suitable for error printouts. 

125 

126 Depends on a 'base_message' string being present in VHDL, as well as a 'message' string 

127 from user which might be empty. 

128 """ 

129 return """\ 

130 function get_message return string is 

131 begin 

132 if message = "" then 

133 return base_message; 

134 end if; 

135 

136 return base_message & " " & message & "."; 

137 end function; 

138"""