1#=========================================================================
2# TestStructuralTranslator.py
3#=========================================================================
4# Author : Peitian Pan
5# Date   : May 20, 2019
6"""Provide a structural translator that fits testing purposes."""
7
8from .. import StructuralTranslator
9
10
11def mk_TestStructuralTranslator( _StructuralTranslator ):
12  def make_indent( src, nindent ):
13    """Add nindent indention to every line in src."""
14    indent = '  '
15    for idx, s in enumerate( src ):
16      src[ idx ] = nindent * indent + s
17
18  def get_string( obj ):
19    """Return the string that identifies `obj`"""
20    if isinstance(obj, type): return obj.__name__
21    return str( obj )
22
23  class TestStructuralTranslator( _StructuralTranslator ):
24    """Testing translator that implements structural callback methods."""
25
26    def rtlir_tr_vector_dtype( s, dtype ):
27      return str( dtype )
28
29    def rtlir_tr_struct_dtype( s, dtype ):
30      return dtype.get_name()
31
32    def rtlir_tr_unpacked_array_type( s, Type ):
33      return "" if Type is None else repr( Type )
34
35    def rtlir_tr_port_decls( s, port_decls ):
36      decls = ''
37      for decl in port_decls:
38        if decl:
39          make_indent( decl, 1 )
40          decls += '\n' + '\n'.join( decl )
41      return f'port_decls:{decls}\n'
42
43    def rtlir_tr_port_decl( s, id_, Type, array_type, dtype ):
44      if id_ not in ["clk", "reset"]:
45        array_type = repr(Type) if not array_type else array_type
46        return [f'port_decl: {id_} {array_type}']
47      else:
48        return ""
49
50    def rtlir_tr_wire_decls( s, wire_decls ):
51      decls = ''
52      for decl in wire_decls:
53        make_indent( decl, 1 )
54        decls += '\n' + '\n'.join( decl )
55      return f'wire_decls:{decls}\n'
56
57    def rtlir_tr_wire_decl( s, id_, Type, array_type, dtype ):
58      array_type = repr(Type) if not array_type else array_type
59      return [f'wire_decl: {id_} {array_type}']
60
61    def rtlir_tr_const_decls( s, const_decls ):
62      decls = ''
63      for decl in const_decls:
64        if decl:
65          make_indent( decl, 1 )
66          decls += '\n' + '\n'.join( decl )
67      return f'const_decls:{decls}\n'
68
69    def rtlir_tr_const_decl( s, id_, Type, array_type, dtype, value ):
70      array_type = repr(Type) if not array_type else array_type
71      return [f'const_decl: {id_} {array_type}']
72
73    def rtlir_tr_interface_port_decls( s, port_decls ):
74      decls = [['interface_ports:']]
75      for decl in port_decls:
76        make_indent( decl, 1 )
77        decls.append( [ decl[0] ] )
78      return decls
79
80    def rtlir_tr_interface_port_decl( s, m, id_, rtype, array_type ):
81      rtype = repr(rtype) if not array_type else array_type
82      return [f'interface_port: {id_} {rtype}']
83
84    def rtlir_tr_interface_decls( s, ifc_decls ):
85      decls = ''
86      for decl in ifc_decls:
87        if decl:
88          make_indent( decl, 1 )
89          decls += '\n' + '\n'.join( decl )
90      return f'interface_decls:{decls}\n'
91
92    def rtlir_tr_interface_decl( s, ifc_id, ifc_rtype, array_type, port_decls ):
93      ifc_rtype = str(ifc_rtype) if not array_type else array_type
94      ret = [f'interface_decl: {ifc_id} {ifc_rtype}']
95      for decl in port_decls:
96        make_indent( decl, 1 )
97        ret.append( decl[0] )
98      return ret
99
100    def rtlir_tr_subcomp_port_decls( s, port_decls ):
101      decls = [['component_ports:']]
102      for decl in port_decls:
103        if decl:
104          make_indent( decl, 1 )
105          decls.append( [ decl[0] ] )
106      return decls
107
108    def rtlir_tr_subcomp_port_decl( s, m, c_id, c_rtype, c_array_type, port_id,
109        port_rtype, port_dtype, array_type ):
110      if port_id not in ["clk", "reset"]:
111        port_rtype = repr(port_rtype) if not array_type else array_type
112        return [f'component_port: {port_id} {port_rtype}']
113      else:
114        return ""
115
116    def rtlir_tr_subcomp_ifc_port_decls( s, ifc_port_decls ):
117      decls = [['component_ifc_ports:']]
118      for decl in ifc_port_decls:
119        if decl:
120          make_indent( decl, 1 )
121          decls.append( [ decl[0] ] )
122      return decls
123
124    def rtlir_tr_subcomp_ifc_port_decl( s, m, c_id, c_rtype, c_array_type,
125        ifc_id, ifc_rtype, ifc_array_type, port_id, port_rtype,
126        port_array_type ):
127      port_rtype = repr(port_rtype) if not port_array_type else port_array_type
128      return [f'component_ifc_port: {port_id} {port_rtype}']
129
130    def rtlir_tr_subcomp_ifc_decls( s, ifc_decls ):
131      decls = [['component_ifcs:']]
132      for ifc_decl in ifc_decls:
133        for decl in ifc_decl:
134          if decl:
135            make_indent( decl, 1 )
136            decls.append( [ decl[0] ] )
137      return decls
138
139    def rtlir_tr_subcomp_ifc_decl( s, m, c_id, c_rtype, c_array_type, ifc_id,
140        ifc_rtype, ifc_array_type, ports ):
141      ifc_rtype = repr(ifc_rtype) if not ifc_array_type else ifc_array_type
142      decls = [[f'component_ifc: {ifc_id} {ifc_rtype}']]
143      for decl in ports:
144        if decl:
145          make_indent( decl, 1 )
146          decls.append( [ decl[0] ] )
147      return decls
148
149    def rtlir_tr_subcomp_decls( s, subcomps ):
150      decls = ''
151      for decl in subcomps:
152        make_indent( decl, 1 )
153        decls += '\n' + '\n'.join( decl )
154      return f'component_decls:{decls}\n'
155
156    def rtlir_tr_subcomp_decl( s, m, c_id, c_rtype, c_array_type, port_conns, ifc_conns ):
157      c_rtype = str(c_rtype) if not c_array_type else c_array_type
158      ret = [f'component_decl: {c_id} {c_rtype}']
159      for port in port_conns:
160        make_indent( port, 1 )
161        ret.append( port[0] )
162      for ifc in ifc_conns:
163        make_indent( ifc, 1 )
164        ret.append( ifc[0] )
165      return ret
166
167    def rtlir_tr_connections( s, connections ):
168      conns = ''
169      for conn in connections:
170        if conn:
171          make_indent( conn, 1 )
172          conns += '\n' + '\n'.join( conn )
173      return f'connections:{conns}\n'
174
175    def rtlir_tr_connection( s, wr, rd ):
176      if "clk" not in wr and "reset" not in wr:
177        return [f'connection: {wr} -> {rd}']
178
179    def rtlir_tr_bit_selection( s, base_signal, index, status ):
180      return f'BitSel {base_signal} {index}'
181
182    def rtlir_tr_part_selection( s, base_signal, start, stop, status ):
183      return f'PartSel {base_signal} {start} {stop}'
184
185    def rtlir_tr_port_array_index( s, base_signal, index, status ):
186      return f'PortArrayIdx {base_signal} {index}'
187
188    def rtlir_tr_wire_array_index( s, base_signal, index, status ):
189      return f'WireArrayIdx {base_signal} {index}'
190
191    def rtlir_tr_const_array_index( s, base_signal, index, status ):
192      return f'ConstArrayIdx {base_signal} {index}'
193
194    def rtlir_tr_packed_index( s, base_signal, index, status ):
195      return f'PackedIndex {base_signal} {index}'
196
197    def rtlir_tr_interface_array_index( s, base_signal, index, status ):
198      return f'IfcArrayIdx {base_signal} {index}'
199
200    def rtlir_tr_component_array_index( s, base_signal, index, status ):
201      return f'CompArrayIdx {base_signal} {index}'
202
203    def rtlir_tr_struct_attr( s, base_signal, attr, status ):
204      return f'StructAttr {base_signal} {attr}'
205
206    def rtlir_tr_interface_attr( s, base_signal, attr, status ):
207      return f'IfcAttr {base_signal} {attr}'
208
209    def rtlir_tr_subcomp_attr( s, base_signal, attr, status ):
210      return f'SubCompAttr {base_signal} {attr}'
211
212    def rtlir_tr_current_comp_attr( s, base_signal, attr, status ):
213      return f'CurCompAttr {attr}'
214
215    def rtlir_tr_current_comp( s, comp_id, comp_rtype, status ):
216      return ''
217
218    def rtlir_tr_var_id( s, var_id ):
219      return var_id
220
221    def rtlir_tr_literal_number( s, nbits, value ):
222      return f'Bits{nbits}({int(value)})'
223
224    def rtlir_tr_component_unique_name( s, c_rtype ):
225      comp_name = c_rtype.get_name()
226      comp_params = c_rtype.get_params()
227      assert comp_name
228      for arg_name, arg_value in comp_params:
229        assert arg_name != ''
230        comp_name += '__' + arg_name + '_' + get_string(arg_value)
231      return comp_name
232
233  return TestStructuralTranslator
234
235TestStructuralTranslator = mk_TestStructuralTranslator( StructuralTranslator )
236