コード例 #1
0
    def visit_Attribute(s, node):
        if isinstance(node.value.Type, rt.Signal):
            dtype = node.value.Type.get_dtype()
            if not isinstance(dtype, rdt.Struct):
                raise PyMTLTypeError(
                    s.blk, node.ast,
                    'attribute base should be a struct signal!')
            if not dtype.has_property(node.attr):
                raise PyMTLTypeError(
                    s.blk, node.ast,
                    f'{dtype.get_name()} does not have field {node.attr}!')
            dtype = dtype.get_property(node.attr)
            if isinstance(node.value.Type, rt.Port):
                rtype = rt.Port(node.value.Type.get_direction(), dtype)
            elif isinstance(node.value.Type, rt.Wire):
                rtype = rt.Wire(dtype)
            elif isinstance(node.value.Type, rt.Const):
                obj = node.value.Type.get_object()
                if obj is None:
                    rtype = rt.Const(dtype)
                else:
                    try:
                        rtype = rt.Const(dtype, getattr(obj, node.attr))
                    except AttributeError:
                        rtype = rt.Const(dtype)
            else:
                raise PyMTLTypeError(
                    s.blk, node.ast,
                    f'unrecognized signal type {node.value.Type}!')
            node.Type = rtype

        else:
            super().visit_Attribute(node)
コード例 #2
0
def test_L1_const_numbers():
    a = CaseConstBits32AttrComp.DUT()
    a.elaborate()
    a.apply(StructuralRTLIRGenL1Pass(gen_connections(a)))
    consts = a.get_metadata(StructuralRTLIRGenL1Pass.consts)
    assert consts == [('const', rt.Array([5],
                                         rt.Const(rdt.Vector(32))), a.const)]
コード例 #3
0
    def visit_StructInst(s, node):
        cls = node.struct

        dtype = rdt.get_rtlir_dtype(cls())
        all_properties = dtype.get_all_properties()

        if len(all_properties) != len(node.values):
            raise PyMTLTypeError(
                s.blk, node.ast,
                f"BitStruct {cls.__name__} has {len(all_properties)} fields but only {len(node.values)} arguments are given!"
            )

        all_types = zip(node.values, list(all_properties.items()))

        for idx, (value, (name, field)) in enumerate(all_types):
            s.visit(value)
            # Expect each argument to be a signal
            if not isinstance(value.Type, rt.Signal):
                raise PyMTLTypeError(
                    s.blk, node.ast,
                    f"argument #{idx} has type {value.Type} but not a signal!")
            v_dtype = value.Type.get_dtype()
            # Expect each argument to have data type which corresponds to the field
            if v_dtype != field:
                raise PyMTLTypeError(
                    s.blk, node.ast,
                    f"Expected argument#{idx} ( field {name} ) to have type {field}, but got {v_dtype}."
                )

        node.Type = rt.Const(dtype)
コード例 #4
0
def test_pymtl_Bits_closure_construct(do_test):
    a = CaseBits32ClosureConstruct.DUT()
    a.elaborate()
    a._rtlir_freevar_ref = {
        'foo_at_upblk': (a.fvar_ref, rt.Const(rdt.Vector(32), a.fvar_ref))
    }
    do_test(a)
コード例 #5
0
def test_L1_const_numbers():
    a = CaseConstBits32AttrComp.DUT()
    a.elaborate()
    a.apply(StructuralRTLIRGenL1Pass(gen_connections(a)))
    ns = a._pass_structural_rtlir_gen
    assert ns.consts == [('const', rt.Array([5], rt.Const(rdt.Vector(32))),
                          a.const)]
コード例 #6
0
ファイル: RTLIRType_test.py プロジェクト: hsqforfun/pymtl3
def test_pymtl3_list_consts():
    class A(dsl.Component):
        def construct(s):
            s.in_ = [Bits32(42) for _ in range(5)]

    a = A()
    a.elaborate()
    assert rt.is_rtlir_convertible(a.in_)
    assert rt.Array([5], rt.Const(rdt.Vector(32))) == rt.get_rtlir(a.in_)
コード例 #7
0
    def visit_BinOp(s, node):
        op = node.op
        l_type = node.left.Type.get_dtype()
        r_type = node.right.Type.get_dtype()
        if not (rdt.Vector(1)(l_type) and rdt.Vector(1)(r_type)):
            raise PyMTLTypeError(
                s.blk, node.ast,
                f"both sides of {op.__class__.__name__} should be of vector type!"
            )

        if not isinstance(op, s.BinOp_left_nbits) and l_type != r_type:
            raise PyMTLTypeError(
                s.blk, node.ast,
                f"LHS and RHS of {op.__class__.__name__} should have the same type ({l_type} vs {r_type})!"
            )

        l_nbits = l_type.get_length()
        r_nbits = r_type.get_length()

        # Enforcing Verilog bitwidth inference rules
        res_nbits = 0
        if isinstance(op, s.BinOp_max_nbits):
            res_nbits = max(l_nbits, r_nbits)
        elif isinstance(op, s.BinOp_left_nbits):
            res_nbits = l_nbits
        else:
            raise Exception('RTLIRTypeCheck internal error: unrecognized op!')

        try:
            # Both sides are constant expressions
            l_val = node.left._value
            r_val = node.rigth._value
            node._value = s.eval_const_binop(l_val, op, r_val)
            node.Type = rt.Const(rdt.Vector(res_nbits))
        except AttributeError:
            # Both sides are constant but the value cannot be determined statically
            if isinstance(node.left.Type, rt.Const) and isinstance(
                    node.right.Type, rt.Const):
                node.Type = rt.Const(rdt.Vector(res_nbits), None)

            # Variable
            else:
                node.Type = rt.NetWire(rdt.Vector(res_nbits))
コード例 #8
0
def test_L1_const_numbers():
    class A(dsl.Component):
        def construct(s):
            s.const = [Bits32(42) for _ in range(5)]

    a = A()
    a.elaborate()
    a.apply(StructuralRTLIRGenL1Pass(*gen_connections(a)))
    ns = a._pass_structural_rtlir_gen
    assert ns.consts == [('const', rt.Array([5], rt.Const(rdt.Vector(32))),
                          a.const)]
コード例 #9
0
  def visit_StructInst( s, node ):
    cls = node.struct

    try:
      type_instance = cls()
    except TypeError:
      raise PyMTLTypeError( s.blk, node.ast,
""""\
__init__ of BitStruct {} should take 0 arguments! You can achieve this by
adding default values to the arguments.
""".format( cls.__name__ ) )

    dtype = rdt.get_rtlir_dtype( cls() )
    all_properties = dtype.get_all_properties()

    if len( all_properties ) != len( node.values ):
      raise PyMTLTypeError( s.blk, node.ast,
        "BitStruct {} has {} fields but only {} arguments are given!". \
            format(cls.__name__, len(all_properties), len(node.values)) )

    all_types = zip( node.values, all_properties )
    for idx, ( value, ( name, field ) ) in enumerate( all_types ):
      s.visit( value )
      # Expect each argument to be a signal
      if not isinstance( value.Type, rt.Signal ):
        raise PyMTLTypeError( s.blk, node.ast,
          "argument #{} has type {} but not a signal!". \
              format( idx, value.Type ) )
      v_dtype = value.Type.get_dtype()
      # Expect each argument to have data type which corresponds to the field
      if v_dtype != field:
        raise PyMTLTypeError( s.blk, node.ast,
          "Expected argument#{} ( field {} ) to have type {}, but got {}.". \
              format( idx, name, field, v_dtype ) )

    node.Type = rt.Const( dtype )
コード例 #10
0
 def visit_LoopVar(s, node):
     node.Type = rt.Const(rdt.Vector(32), None)
コード例 #11
0
 def __init__(s, obj, value):
     super().__init__(rt.Const(rdt.get_rtlir_dtype(obj)))
     s.value = value
コード例 #12
0
ファイル: RTLIRType_test.py プロジェクト: lneuhaus/pymtl3
def test_pymtl3_list_consts():
    a = CaseBits32x5ConstOnly.DUT()
    a.elaborate()
    assert rt.is_rtlir_convertible(a.in_)
    assert rt.get_rtlir(a.in_) == rt.Array([5], rt.Const(rdt.Vector(32)))
コード例 #13
0
def test_pymtl_Bits_global(do_test):
    a = CaseBits32ClosureGlobal.DUT()
    a.elaborate()
    a._rtlir_freevar_ref = \
      { 'pymtl_Bits_global_freevar' : ( pymtl_Bits_global_freevar, rt.Const(rdt.Vector(32), pymtl_Bits_global_freevar) ) }
    do_test(a)
コード例 #14
0
    def visit_BinOp(s, node):
        op = node.op
        l_type = node.left.Type.get_dtype()
        r_type = node.right.Type.get_dtype()
        l_explicit, r_explicit = node.left._is_explicit, node.right._is_explicit
        if not (rdt.Vector(1)(l_type) and rdt.Vector(1)(r_type)):
            raise PyMTLTypeError(
                s.blk, node.ast,
                f"both sides of {op.__class__.__name__} should be of vector type!"
            )

        l_nbits = l_type.get_length()
        r_nbits = r_type.get_length()

        # Enforcing Verilog bitwidth inference rules
        res_nbits = 0
        if isinstance(op, s.BinOp_max_nbits):
            if (not l_explicit and r_explicit) or (l_explicit
                                                   and not r_explicit):

                context, op, explicit, implicit = node.left.Type, node.right, l_nbits, r_nbits
                if not l_explicit:
                    context, op, explicit, implicit = node.right.Type, node.left, r_nbits, l_nbits
                # Check if any implicit truncation happens
                if explicit < implicit:
                    raise PyMTLTypeError(
                        s.blk, node.ast,
                        f"The explicitly sized side of operation has {explicit} bits but "
                        f"the integer literal requires more bits ({implicit})!"
                    )
                s.enforcer.enter(s.blk, context, op)

            elif not l_explicit and not r_explicit:
                # Both sides are implicit
                if l_nbits >= r_nbits:
                    target_nbits = l_nbits
                    op = node.right
                else:
                    target_nbits = r_nbits
                    op = node.left
                context = rt.NetWire(rdt.Vector(target_nbits))
                s.enforcer.enter(s.blk, context, op)

            else:
                # Both sides are explicit
                if not isinstance(op, s.BinOp_left_nbits) and l_type != r_type:
                    raise PyMTLTypeError(
                        s.blk, node.ast,
                        f"LHS and RHS of {op.__class__.__name__} should have the same type ({l_type} vs {r_type})!"
                    )

            res_nbits = max(l_nbits, r_nbits)
            node._is_explicit = l_explicit or r_explicit

        elif isinstance(op, s.BinOp_left_nbits):
            res_nbits = l_nbits
            node._is_explicit = l_explicit

        else:
            raise Exception('RTLIRTypeCheck internal error: unrecognized op!')

        try:
            # Both sides are constant expressions
            l_val = node.left._value
            r_val = node.right._value
            node._value = s.eval_const_binop(l_val, node.op, r_val)
            node.Type = s.rtlir_getter.get_rtlir(node._value)
            assert isinstance(node.Type, rt.Const)
        except AttributeError:
            # Both sides are constant but the value cannot be determined statically
            if isinstance(node.left.Type, rt.Const) and isinstance(
                    node.right.Type, rt.Const):
                node.Type = rt.Const(rdt.Vector(res_nbits), None)
            # Variable
            else:
                node.Type = rt.NetWire(rdt.Vector(res_nbits))
コード例 #15
0
 def visit_LoopVar(s, node):
     node.Type = rt.Const(rdt.Vector(s.loopvar_nbits[node.name]), None)
     node._is_explicit = s.loopvar_is_explicit[node.name]