99
1010import autopep8 # type: ignore
1111import jinja2 as jj
12+ from systemrdl import RDLWalker # type: ignore
1213
1314from systemrdl .node import RootNode , Node , RegNode , AddrmapNode , RegfileNode # type: ignore
1415from systemrdl .node import FieldNode , MemNode , AddressableNode # type: ignore
2829
2930from .safe_name_utility import get_python_path_segments , safe_node_name
3031
32+ from ._node_walkers import AddressMaps , OwnedbyAddressMap
33+
3134from .__about__ import __version__
3235
3336file_path = os .path .dirname (__file__ )
@@ -115,78 +118,145 @@ def export(self, node: Node, path: str,
115118
116119 # If it is the root node, skip to top addrmap
117120 if isinstance (node , RootNode ):
118- node = node .top
121+ top_block = node .top
122+ else :
123+ top_block = node
119124
120125 package_path = os .path .join (path , node .inst_name )
121126 self ._create_empty_package (package_path = package_path ,
122127 skip_test_case_generation = skip_test_case_generation )
123128
124- modules = [node ]
129+ self ._build_node_type_table (top_block )
130+
131+ context = {
132+ 'print' : print ,
133+ 'type' : type ,
134+ 'top_node' : top_block ,
135+ 'systemrdlFieldNode' : FieldNode ,
136+ 'systemrdlRegNode' : RegNode ,
137+ 'systemrdlRegfileNode' : RegfileNode ,
138+ 'systemrdlAddrmapNode' : AddrmapNode ,
139+ 'systemrdlMemNode' : MemNode ,
140+ 'systemrdlAddressableNode' : AddressableNode ,
141+ 'systemrdlSignalNode' : SignalNode ,
142+ 'asyncoutput' : asyncoutput ,
143+ 'OnWriteType' : OnWriteType ,
144+ 'OnReadType' : OnReadType ,
145+ 'PropertyReference' : PropertyReference ,
146+ 'isinstance' : isinstance ,
147+ 'uses_enum' : uses_enum (top_block ),
148+ 'uses_memory' : uses_memory (top_block ),
149+ 'get_fully_qualified_type_name' : self ._lookup_type_name ,
150+ 'get_array_dim' : get_array_dim ,
151+ 'get_dependent_component' : get_dependent_component ,
152+ 'get_dependent_enum' : self ._get_dependent_enum ,
153+ 'get_enum_values' : get_enum_values ,
154+ 'get_fully_qualified_enum_type' : self ._fully_qualified_enum_type ,
155+ 'get_field_bitmask_hex_string' : get_field_bitmask_hex_string ,
156+ 'get_field_inv_bitmask_hex_string' : get_field_inv_bitmask_hex_string ,
157+ 'get_field_max_value_hex_string' : get_field_max_value_hex_string ,
158+ 'get_reg_max_value_hex_string' : get_reg_max_value_hex_string ,
159+ 'get_table_block' : get_table_block ,
160+ 'get_reg_writable_fields' : get_reg_writable_fields ,
161+ 'get_reg_readable_fields' : get_reg_readable_fields ,
162+ 'get_memory_max_entry_value_hex_string' : get_memory_max_entry_value_hex_string ,
163+ 'get_array_typecode' : get_array_typecode ,
164+ 'get_memory_width_bytes' : get_memory_width_bytes ,
165+ 'get_field_default_value' : get_field_default_value ,
166+ 'raise_template_error' : self ._raise_template_error ,
167+ 'get_python_path_segments' : get_python_path_segments ,
168+ 'safe_node_name' : safe_node_name ,
169+ 'version' : __version__
170+ }
171+
172+ context .update (self .user_template_context )
173+
174+ template = self .jj_env .get_template ("addrmap.py.jinja" )
175+ module_fqfn = os .path .join (package_path ,
176+ 'reg_model' ,
177+ top_block .inst_name + '.py' )
178+ if autoformatoutputs is True :
179+ module_code_str = autopep8 .fix_code (template .render (context ))
180+ with open (module_fqfn , "w" , encoding = 'utf-8' ) as fid :
181+ fid .write (module_code_str )
182+ else :
183+ stream = template .stream (context )
184+ stream .dump (module_fqfn , encoding = 'utf-8' )
125185
126- for block in modules :
186+ if not skip_test_case_generation :
127187
128- self ._build_node_type_table (block )
188+ # make the top level base class for all the other test, this is what instantes
189+ # the register model
190+ template = self .jj_env .get_template ("baseclass_tb.py.jinja" )
191+ module_tb_fqfn = os .path .join (package_path ,
192+ 'tests' ,
193+ '_' + top_block .inst_name + '_test_base.py' )
129194
130195 context = {
131- 'print' : print ,
132- 'type' : type ,
133- 'top_node' : block ,
134- 'systemrdlFieldNode' : FieldNode ,
135- 'systemrdlRegNode' : RegNode ,
136- 'systemrdlRegfileNode' : RegfileNode ,
137- 'systemrdlAddrmapNode' : AddrmapNode ,
138- 'systemrdlMemNode' : MemNode ,
139- 'systemrdlAddressableNode' : AddressableNode ,
140- 'systemrdlSignalNode' : SignalNode ,
196+ 'top_node' : top_block ,
141197 'asyncoutput' : asyncoutput ,
142- 'OnWriteType' : OnWriteType ,
143- 'OnReadType' : OnReadType ,
144- 'PropertyReference' : PropertyReference ,
145- 'isinstance' : isinstance ,
146- 'uses_enum' : uses_enum (block ),
147- 'uses_memory' : uses_memory (block ),
148- 'get_fully_qualified_type_name' : self ._lookup_type_name ,
149- 'get_array_dim' : get_array_dim ,
150- 'get_dependent_component' : get_dependent_component ,
151- 'get_dependent_enum' : self ._get_dependent_enum ,
152- 'get_enum_values' : get_enum_values ,
153- 'get_fully_qualified_enum_type' : self ._fully_qualified_enum_type ,
154- 'get_field_bitmask_hex_string' : get_field_bitmask_hex_string ,
155- 'get_field_inv_bitmask_hex_string' : get_field_inv_bitmask_hex_string ,
156- 'get_field_max_value_hex_string' : get_field_max_value_hex_string ,
157- 'get_reg_max_value_hex_string' : get_reg_max_value_hex_string ,
158- 'get_table_block' : get_table_block ,
159- 'get_reg_writable_fields' : get_reg_writable_fields ,
160- 'get_reg_readable_fields' : get_reg_readable_fields ,
161- 'get_memory_max_entry_value_hex_string' : get_memory_max_entry_value_hex_string ,
162- 'get_array_typecode' : get_array_typecode ,
163- 'get_memory_width_bytes' : get_memory_width_bytes ,
164- 'get_field_default_value' : get_field_default_value ,
165- 'raise_template_error' : self ._raise_template_error ,
166- 'get_python_path_segments' : get_python_path_segments ,
167- 'safe_node_name' : safe_node_name ,
168- 'version' : __version__
198+ 'version' : __version__
169199 }
170200
171- context .update (self .user_template_context )
172-
173- template = self .jj_env .get_template ("addrmap.py.jinja" )
174- module_fqfn = os .path .join (package_path ,
175- 'reg_model' ,
176- block .inst_name + '.py' )
177201 if autoformatoutputs is True :
178- module_code_str = autopep8 .fix_code (template .render (context ))
179- with open (module_fqfn , "w" , encoding = 'utf-8' ) as fid :
180- fid .write (module_code_str )
202+ module_tb_code_str = autopep8 .fix_code (template .render (context ))
203+ with open (module_tb_fqfn , "w" , encoding = 'utf-8' ) as fid :
204+ fid .write (module_tb_code_str )
181205 else :
182206 stream = template .stream (context )
183- stream .dump (module_fqfn , encoding = 'utf-8' )
207+ stream .dump (module_tb_fqfn , encoding = 'utf-8' )
208+
209+ # make the tests themselves
210+ template = self .jj_env .get_template ("addrmap_tb.py.jinja" )
211+
212+ blocks = AddressMaps ()
213+ # running the walker populated the blocks with all the address maps in within the
214+ # top block, including the top_block itself
215+ RDLWalker (unroll = True ).walk (top_block , blocks , skip_top = False )
216+
217+ for block in blocks :
218+ owned_elements = OwnedbyAddressMap ()
219+ # running the walker populated the blocks with all the address maps in within the
220+ # top block, including the top_block itself
221+ RDLWalker (unroll = True ).walk (block , owned_elements , skip_top = True )
222+
223+ fq_block_name = '_' .join (block .get_path_segments (array_suffix = '_{index:d}_' ))
184224
185- if not skip_test_case_generation :
186- template = self .jj_env .get_template ("addrmap_tb.py.jinja" )
187225 module_tb_fqfn = os .path .join (package_path ,
188226 'tests' ,
189- 'test_' + block .inst_name + '.py' )
227+ 'test_' + fq_block_name + '.py' )
228+
229+ context = {
230+ 'top_node' : top_block ,
231+ 'block' : block ,
232+ 'fq_block_name' : fq_block_name ,
233+ 'owned_elements' : owned_elements ,
234+ 'systemrdlFieldNode' : FieldNode ,
235+ 'systemrdlSignalNode' : SignalNode ,
236+ 'systemrdlRegNode' : RegNode ,
237+ 'systemrdlMemNode' : MemNode ,
238+ 'systemrdlRegfileNode' : RegfileNode ,
239+ 'systemrdlAddrmapNode' : AddrmapNode ,
240+ 'isinstance' : isinstance ,
241+ 'get_python_path_segments' : get_python_path_segments ,
242+ 'safe_node_name' : safe_node_name ,
243+ 'uses_memory' : (len (owned_elements .memories ) > 0 ),
244+ 'get_field_bitmask_hex_string' : get_field_bitmask_hex_string ,
245+ 'get_field_inv_bitmask_hex_string' : get_field_inv_bitmask_hex_string ,
246+ 'get_field_max_value_hex_string' : get_field_max_value_hex_string ,
247+ 'get_field_default_value' : get_field_default_value ,
248+ 'get_reg_max_value_hex_string' : get_reg_max_value_hex_string ,
249+ 'get_reg_writable_fields' : get_reg_writable_fields ,
250+ 'get_reg_readable_fields' : get_reg_readable_fields ,
251+ 'get_memory_max_entry_value_hex_string' : get_memory_max_entry_value_hex_string ,
252+ 'get_enum_values' : get_enum_values ,
253+ 'get_array_typecode' : get_array_typecode ,
254+ 'get_memory_width_bytes' : get_memory_width_bytes ,
255+ 'asyncoutput' : asyncoutput ,
256+ 'uses_enum' : uses_enum (block ),
257+ 'version' : __version__
258+ }
259+
190260 if autoformatoutputs is True :
191261 module_tb_code_str = autopep8 .fix_code (template .render (context ))
192262 with open (module_tb_fqfn , "w" , encoding = 'utf-8' ) as fid :
@@ -195,7 +265,7 @@ def export(self, node: Node, path: str,
195265 stream = template .stream (context )
196266 stream .dump (module_tb_fqfn , encoding = 'utf-8' )
197267
198- return [ m .inst_name for m in modules ]
268+ return top_block .inst_name
199269
200270 def _lookup_type_name (self , node : Node ) -> str :
201271 """
0 commit comments