1#========================================================================= 2# VStructuralTranslatorL2.py 3#========================================================================= 4"""Provide SystemVerilog structural translator implementation.""" 5 6from textwrap import dedent 7 8from pymtl3.passes.backends.generic.structural.StructuralTranslatorL2 import ( 9 StructuralTranslatorL2, 10) 11from pymtl3.passes.rtlir import RTLIRDataType as rdt 12 13from ...util.utility import make_indent, pretty_concat 14from .VStructuralTranslatorL1 import VStructuralTranslatorL1 15 16 17class VStructuralTranslatorL2( 18 VStructuralTranslatorL1, StructuralTranslatorL2 ): 19 20 #----------------------------------------------------------------------- 21 # Data types 22 #----------------------------------------------------------------------- 23 24 def rtlir_tr_packed_array_dtype( s, dtype ): 25 sub_dtype = dtype.get_sub_dtype() 26 if isinstance( sub_dtype, rdt.Vector ): 27 sub_dtype_tr = s.rtlir_tr_vector_dtype( sub_dtype ) 28 elif isinstance( sub_dtype, rdt.Struct ): 29 sub_dtype_tr = s.rtlir_tr_struct_dtype( sub_dtype ) 30 else: 31 assert False, f"unsupported data type {sub_dtype} in packed array!" 32 dim_str = "".join( f"[{size-1}:0]" for size in dtype.get_dim_sizes() ) 33 return { 34 'def' : '', 35 'data_type' : f"{sub_dtype_tr['data_type']}", 36 'packed_type' : f"{dim_str}{sub_dtype_tr['packed_type']}", 37 'unpacked_type' : sub_dtype_tr['unpacked_type'], 38 'ndim' : dtype.get_dim_sizes(), 39 'raw_dtype' : dtype 40 } 41 42 def rtlir_tr_struct_dtype( s, dtype ): 43 dtype_name = dtype.get_name() 44 field_decls = [] 45 46 for id_, _dtype in dtype.get_all_properties().items(): 47 48 if isinstance( _dtype, rdt.Vector ): 49 tr = s.rtlir_tr_vector_dtype(_dtype) 50 elif isinstance( _dtype, rdt.PackedArray ): 51 tr = s.rtlir_tr_packed_array_dtype(_dtype) 52 elif isinstance( _dtype, rdt.Struct ): 53 tr = s.rtlir_tr_struct_dtype(_dtype) 54 else: 55 assert False, \ 56 f'unrecoganized field type {_dtype} of struct {dtype_name}!' 57 field_decls.append(pretty_concat(tr['data_type'], tr['packed_type'], id_, ';')) 58 59 make_indent( field_decls, 1 ) 60 field_decl = '\n'.join( field_decls ) 61 62 return { 63 'def' : dedent("""\ 64 typedef struct packed {{ 65 {field_decl} 66 }} {dtype_name}; 67 """).format(**locals()), 68 'nbits' : dtype.get_length(), 69 'data_type' : dtype_name, 70 'packed_type' : '', 71 'unpacked_type' : '', 72 'raw_dtype' : dtype 73 } 74 75 #----------------------------------------------------------------------- 76 # Declarations 77 #----------------------------------------------------------------------- 78 79 def gen_array_param( s, n_dim, dtype, array ): 80 if not n_dim and isinstance( dtype, rdt.Struct ): 81 return s.rtlir_tr_struct_instance( dtype, array ) 82 else: 83 return super().gen_array_param( n_dim, dtype, array ) 84 85 #----------------------------------------------------------------------- 86 # Signal oeprations 87 #----------------------------------------------------------------------- 88 89 def rtlir_tr_packed_index( s, base_signal, index, status ): 90 return s._rtlir_tr_process_unpacked( 91 f'{base_signal}[{index}]', 92 f'{base_signal}{{}}[{index}]', 93 status, ('status', 'unpacked') ) 94 95 def rtlir_tr_struct_attr( s, base_signal, attr, status ): 96 return s._rtlir_tr_process_unpacked( 97 f'{base_signal}.{attr}', 98 f'{base_signal}{{}}.{attr}', 99 status, ('status', 'unpacked') ) 100 101 def rtlir_tr_struct_instance( s, dtype, struct ): 102 def _gen_packed_array( dtype, n_dim, array ): 103 if not n_dim: 104 if isinstance( dtype, rdt.Vector ): 105 return s.rtlir_tr_literal_number( dtype.nbits, array ) 106 elif isinstance( dtype, rdt.Struct ): 107 return s.rtlir_tr_struct_instance( dtype, array ) 108 else: 109 assert False, f"unrecognized data type {dtype}!" 110 else: 111 ret = [] 112 for i in reversed( range( n_dim[0]) ): 113 ret.append( _gen_packed_array( dtype, n_dim[1:], array[i] ) ) 114 if n_dim[0] > 1: 115 cat_str = "{" + ", ".join( ret ) + "}" 116 else: 117 cat_str = ", ".join( ret ) 118 return f"{{ {cat_str} }}" 119 ret = [] 120 for name, Type in dtype.get_all_properties().items(): 121 field = getattr( struct, name ) 122 if isinstance( Type, rdt.Vector ): 123 _ret = s.rtlir_tr_literal_number( Type.nbits, field ) 124 elif isinstance( Type, rdt.Struct ): 125 _ret = s.rtlir_tr_struct_instance( Type, field ) 126 elif isinstance( Type, rdt.PackedArray ): 127 n_dim = Type.get_dim_sizes() 128 sub_dtype = Type.get_sub_dtype() 129 _ret = _gen_packed_array( sub_dtype, n_dim, field ) 130 else: 131 assert False, f"unrecognized data type {Type}!" 132 ret.append( _ret ) 133 return f"{{ {', '.join(ret)} }}" 134