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

35 statements  

« prev     ^ index     » next       coverage.py v7.6.8, created at 2024-12-01 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 

10# Standard libraries 

11from typing import TYPE_CHECKING, Optional 

12 

13# First party libraries 

14from hdl_registers.generator.vhdl.vhdl_generator_common import VhdlGeneratorCommon 

15 

16if TYPE_CHECKING: 

17 # First party libraries 

18 from hdl_registers.register import Register 

19 from hdl_registers.register_array import RegisterArray 

20 

21 

22class VhdlSimulationGeneratorCommon(VhdlGeneratorCommon): 

23 """ 

24 Common methods for generation of VHDL simulation code. 

25 """ 

26 

27 def get_array_index_port(self, register_array: Optional["RegisterArray"]) -> str: 

28 """ 

29 Get the array index port declaration. 

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

31 """ 

32 if register_array: 

33 array_name = self.qualified_register_array_name(register_array=register_array) 

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

35 

36 return "" 

37 

38 @staticmethod 

39 def get_array_index_association(register_array: Optional["RegisterArray"]) -> str: 

40 """ 

41 Get the array index association. 

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

43 """ 

44 if register_array: 

45 return " array_index => array_index,\n" 

46 

47 return "" 

48 

49 def reg_index_constant( 

50 self, register: "Register", register_array: Optional["RegisterArray"] = None 

51 ) -> str: 

52 """ 

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

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

55 being present in the VHDL. 

56 

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

58 """ 

59 register_name = self.qualified_register_name( 

60 register=register, register_array=register_array 

61 ) 

62 reg_index = ( 

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

64 ) 

65 

66 return f" constant reg_index : {self.name}_reg_range := {reg_index};\n" 

67 

68 @staticmethod 

69 def reg_address_constant() -> str: 

70 """ 

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

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

73 

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

75 """ 

76 return ( 

77 " constant reg_address : addr_t := base_address + " 

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

79 ) 

80 

81 @staticmethod 

82 def get_register_array_message( 

83 register_array: Optional["RegisterArray"], 

84 ) -> str: 

85 """ 

86 Status message for register array information. 

87 Suitable for error printouts. 

88 

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

90 be available as an integer in VHDL. 

91 """ 

92 if register_array: 

93 register_array_message = ( 

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

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

96 ) 

97 else: 

98 register_array_message = "" 

99 

100 return f"""\ 

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

102""" 

103 

104 @staticmethod 

105 def get_base_address_message() -> str: 

106 """ 

107 Status message for base address information. 

108 Suitable for error printouts. 

109 

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

111 """ 

112 return """\ 

113 function base_address_message return string is 

114 begin 

115 if base_address /= 0 then 

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

117 end if; 

118 

119 return ""; 

120 end function; 

121""" 

122 

123 @staticmethod 

124 def get_message() -> str: 

125 """ 

126 Get the compounded status message. 

127 Suitable for error printouts. 

128 

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

130 from user which might be empty. 

131 """ 

132 return """\ 

133 function get_message return string is 

134 begin 

135 if message = "" then 

136 return base_message; 

137 end if; 

138 

139 return base_message & " " & message & "."; 

140 end function; 

141"""