1#========================================================================= 2# StructuralRTLIRGenL1Pass.py 3#========================================================================= 4# Author : Shunning Jiang, Peitian Pan 5# Date : Apr 3, 2019 6"""Provide L1 structural RTLIR generation pass.""" 7 8from pymtl3 import MetadataKey 9from pymtl3.passes.PlaceholderConfigs import PlaceholderConfigs 10# from pymtl3.passes.rtlir.RTLIRPass import RTLIRPass 11from pymtl3.passes.rtlir.errors import RTLIRConversionError 12from pymtl3.passes.rtlir.rtype.RTLIRType import RTLIRGetter 13 14from .StructuralRTLIRGenL0Pass import StructuralRTLIRGenL0Pass 15from .StructuralRTLIRSignalExpr import gen_signal_expr 16 17 18class StructuralRTLIRGenL1Pass( StructuralRTLIRGenL0Pass ): 19 20 def __init__( s, inst_conns ): 21 s.inst_conns = inst_conns 22 23 def __call__( s, tr_top ): 24 """ generate structural RTLIR for component `tr_top` """ 25 c = s.__class__ 26 s.tr_top = tr_top 27 if not tr_top.has_metadata( c.rtlir_getter ): 28 tr_top.set_metadata( c.rtlir_getter, RTLIRGetter(cache=True) ) 29 30 try: 31 s._gen_metadata( tr_top ) 32 except AssertionError as e: 33 msg = '' if not e.args is None else e.args[0] 34 raise RTLIRConversionError( tr_top, msg ) 35 36 def _gen_metadata( s, m ): 37 c = s.__class__ 38 39 # Generate RTLIR types 40 rtlir_type = s.tr_top.get_metadata( c.rtlir_getter ).get_rtlir( m ) 41 m.set_metadata( c.rtlir_type, rtlir_type ) 42 43 # Generate constants 44 consts = [] 45 rtype = rtlir_type 46 const_types = rtype.get_consts_packed() 47 for const_name, const_rtype in const_types: 48 assert hasattr(m, const_name), \ 49 f"Internal error: {const_name} is not a member of {m}" 50 const_instance = getattr(m, const_name) 51 consts.append( ( const_name, const_rtype, const_instance ) ) 52 53 m.set_metadata( c.consts, consts ) 54 55 # Sort connections 56 m_conns_set = s.inst_conns[m] 57 ordered_conns = [ *m.get_connect_order() ] 58 59 # NOTE: this assertion can fail due to connections that 60 # are made outside the component that has them. so i'm removing 61 # this for now until we can figure out a better way to do sanity 62 # check here. 63 # assert len(ordered_conns) == len(m_conns_set) 64 65 for i, x in enumerate(ordered_conns): 66 if x not in m_conns_set: 67 x = (x[1], x[0]) 68 assert x in m_conns_set, "There is a connection missing from "\ 69 "connect_order. Please contact PyMTL developers!" 70 ordered_conns[i] = x 71 72 connections = [ (gen_signal_expr(m, x[0]), gen_signal_expr(m, x[1])) for x in ordered_conns ] 73 74 m.set_metadata( c.connections, connections ) 75