Beispiel #1
0
def subsignalsection_legalizer(optree, input_prec_solver=default_prec_solver):
    if is_fixed_point(optree.get_precision()) and is_fixed_point(
            optree.get_input(0).get_precision()):
        return legalize_fixed_point_subselection(
            optree, input_prec_solver=input_prec_solver)
    else:
        return optree
Beispiel #2
0
def solve_format_ArithOperation(
        optree,
        integer_size_func=lambda lhs_prec, rhs_prec: None,
        frac_size_func=lambda lhs_prec, rhs_prec: None,
        signed_func=lambda lhs, lhs_prec, rhs, rhs_prec: False):
    """ determining fixed-point format for a generic 2-op arithmetic
        operation (e.g. Multiplication, Addition, Subtraction)
    """
    lhs = optree.get_input(0)
    rhs = optree.get_input(1)
    lhs_precision = lhs.get_precision()
    rhs_precision = rhs.get_precision()

    abstract_operation = (lhs_precision is ML_Integer) and (rhs_precision is
                                                            ML_Integer)
    if abstract_operation:
        return ML_Integer

    if lhs_precision is ML_Integer:
        cst_eval = evaluate_cst_graph(lhs, input_prec_solver=solve_format_rec)
        lhs_precision = solve_format_Constant(Constant(cst_eval))

    if rhs_precision is ML_Integer:
        cst_eval = evaluate_cst_graph(rhs, input_prec_solver=solve_format_rec)
        rhs_precision = solve_format_Constant(Constant(cst_eval))

    if is_fixed_point(lhs_precision) and is_fixed_point(rhs_precision):
        # +1 for carry overflow
        int_size = integer_size_func(lhs_precision, rhs_precision)
        frac_size = frac_size_func(lhs_precision, rhs_precision)
        is_signed = signed_func(lhs, lhs_precision, rhs, rhs_precision)
        return fixed_point(int_size, frac_size, signed=is_signed)
    else:
        return optree.get_precision()
Beispiel #3
0
def add_signed_predicate(lhs, lhs_prec, rhs, rhs_prec):
    """ determine whether subtraction output on a signed or
        unsigned format """
    if is_fixed_point(lhs_prec) and is_fixed_point(rhs_prec):
        default = lhs_prec.get_signed() or rhs_prec.get_signed()
    else:
        default = True
    return addsub_signed_predicate(lhs, lhs_prec, rhs, rhs_prec, op=operator.__add__, default=default)
def test_format_equality(format0, format1):
    if format0 == format1:
        return True
    elif is_fixed_point(format0) and is_fixed_point(format1):
        return \
            (format0.get_integer_size() == format1.get_integer_size()) and \
            (format0.get_frac_size() == format1.get_frac_size()) and \
            (format0.get_signed() == format1.get_signed())
    return False
Beispiel #5
0
def propagate_format_to_input(new_format, optree, input_index_list):
    """ Propgate new_format to @p optree's input whose index is listed in
        @p input_index_list """
    for op_index in input_index_list:
        op_input = optree.get_input(op_index)
        if op_input.get_precision() is None:
            op_input.set_precision(new_format)
            index_list = does_node_propagate_format(op_input)
            propagate_format_to_input(new_format, op_input, index_list)
        elif not test_format_equality(new_format, op_input.get_precision()):
            if is_constant(op_input):
                if not is_fixed_point(new_format):
                    Log.report(
                        Log.Error,
                        "format {} during propagation to input {} of {} is not a fixed-point format",
                        new_format, op_input, optree)
                elif format_does_fit(op_input, new_format):
                    Log.report(
                        Log.Info,
                        "Simplify Constant Conversion {} to larger Constant: {}",
                        op_input.get_str(display_precision=True)
                        if Log.is_level_enabled(Log.Info) else "",
                        str(new_format))
                    new_input = op_input.copy()
                    new_input.set_precision(new_format)
                    optree.set_input(op_index, new_input)
                else:
                    Log.report(
                        Log.Error,
                        "Constant is about to be reduced to a too constrained format: {}",
                        op_input.get_str(display_precision=True)
                        if Log.is_level_enabled(Log.Error) else "")
            else:
                new_input = Conversion(op_input, precision=new_format)
                optree.set_input(op_index, new_input)
Beispiel #6
0
def solve_format_SubSignalSelection(optree, format_solver):
    """ Dummy legalization of SubSignalSelection operation node """
    if optree.get_precision() is None:
        select_input = optree.get_input(0)
        input_prec = select_input.get_precision()

        inf_index = evaluate_cst_graph(optree.get_inf_index(),
                                       input_prec_solver=format_solver)
        sup_index = evaluate_cst_graph(optree.get_sup_index(),
                                       input_prec_solver=format_solver)

        if is_fixed_point(input_prec):
            frac_size = input_prec.get_frac_size() - inf_index
            integer_size = input_prec.get_integer_size() - (
                input_prec.get_bit_size() - 1 - sup_index)
            if frac_size + integer_size <= 0:
                Log.report(
                    Log.Error,
                    "range determined for SubSignalSelection format [{}:{}] has negative size: {}, optree is {}",
                    integer_size, frac_size, integer_size + frac_size, optree)
            return fixed_point(integer_size, frac_size)
        else:
            return ML_StdLogicVectorFormat(sup_index - inf_index + 1)
    else:
        return optree.get_precision()
Beispiel #7
0
def fixed_point_position_legalizer(optree,
                                   input_prec_solver=default_prec_solver):
    """ Legalize a FixedPointPosition node to a constant """
    assert isinstance(optree, FixedPointPosition)
    fixed_input = optree.get_input(0)
    fixed_precision = input_prec_solver(fixed_input)
    if not is_fixed_point(fixed_precision):
        Log.report(
            Log.Error,
            "in fixed_point_position_legalizer: precision of {} should be fixed-point but is {}"
            .format(fixed_input, fixed_precision))

    position = optree.get_input(1).get_value()

    align = optree.get_align()

    value_computation_map = {
        FixedPointPosition.FromLSBToLSB:
        position,
        FixedPointPosition.FromMSBToLSB:
        fixed_precision.get_bit_size() - 1 - position,
        FixedPointPosition.FromPointToLSB:
        fixed_precision.get_frac_size() + position,
        FixedPointPosition.FromPointToMSB:
        fixed_precision.get_integer_size() - position
    }
    cst_value = value_computation_map[align]
    # display value
    Log.report(
        Log.LogLevel("FixedPoint"),
        "fixed-point position {tag} has been resolved to {value}".format(
            tag=optree.get_tag(), value=cst_value))
    result = Constant(cst_value, precision=ML_Integer)
    forward_attributes(optree, result)
    return result
Beispiel #8
0
def solve_format_CLZ(optree):
    """ Legalize CountLeadingZeros precision
    
        Args:
            optree (CountLeadingZeros): input node
            
        Returns:
            ML_Format: legal format for CLZ
    """
    assert isinstance(optree, CountLeadingZeros)
    op_input = optree.get_input(0)
    input_precision = op_input.get_precision()

    if is_fixed_point(input_precision):
        if input_precision.get_signed():
            Log.report(Log.Warning , "signed format in solve_format_CLZ")
        # +1 for carry overflow
        int_size = int(sollya.floor(sollya.log2(input_precision.get_bit_size()))) + 1 
        frac_size = 0
        return fixed_point(
            int_size,
            frac_size,
            signed=False
        )
    else:
        Log.report(Log.Warning , "unsupported format in solve_format_CLZ")
        return optree.get_precision()
Beispiel #9
0
def generate_random_fixed_value(precision):
    """ Generate a random fixed-point value of format precision """
    assert is_fixed_point(precision)
    # fixed point format
    lo_value = precision.get_min_value()
    hi_value = precision.get_max_value()
    value = random.uniform(lo_value, hi_value)
    rounded_value = precision.round_sollya_object(value)
    return rounded_value
Beispiel #10
0
def solve_format_shift(optree):
    """ Legalize shift node """
    assert isinstance(optree, BitLogicRightShift) or isinstance(
        optree, BitLogicLeftShift)
    shift_input = optree.get_input(0)
    shift_input_precision = shift_input.get_precision()
    shift_amount = optree.get_input(1)

    shift_amount_prec = shift_amount.get_precision()
    if is_fixed_point(shift_amount_prec):
        sa_range = evaluate_range(shift_amount)
        if sollya.inf(sa_range) < 0:
            Log.report(
                Log.Error, "shift amount of {} may be negative {}\n".format(
                    optree, sa_range))
    if is_fixed_point(shift_input_precision):
        return shift_input_precision
    else:
        return optree.get_precision()
Beispiel #11
0
def format_does_fit(cst_optree, new_format):
    """ Test if @p cst_optree fits into the precision @p new_format """
    assert is_constant(cst_optree)
    assert is_fixed_point(new_format)
    min_format = solve_format_Constant(cst_optree)
    sign_bias = 1 if (new_format.get_signed() and not min_format.get_signed()) \
        else 0
    return (new_format.get_integer_size() - sign_bias) >= \
        min_format.get_integer_size() and \
        new_format.get_frac_size() >= min_format.get_frac_size() and \
           (new_format.get_signed() or not min_format.get_signed())
Beispiel #12
0
def solve_format_bitwise_op(optree):
    """ legalize format of bitwise logical operation

        Args:
            optree (ML_Operation): bitwise logical input node

        Returns:
            (ML_Format): legal format for input node
    """
    lhs = optree.get_input(0)
    rhs = optree.get_input(1)
    lhs_precision = lhs.get_precision()
    rhs_precision = rhs.get_precision()

    if is_fixed_point(lhs_precision) and is_fixed_point(rhs_precision):
        assert(lhs_precision.get_integer_size() == rhs_precision.get_integer_size())
        assert(lhs_precision.get_frac_size() == rhs_precision.get_frac_size())
        return lhs_precision
    else:
        return optree.get_precision()
Beispiel #13
0
def format_does_fit(cst_optree, new_format):
    """ Test if @p cst_optree fits into the precision @p new_format """
    assert is_constant(cst_optree)
    assert is_fixed_point(new_format)
    # min_format is a dummy format used simply to check
    # if constant fits in new_format
    min_format = determine_minimal_fixed_format_cst(cst_optree.get_value())
    sign_bias = 1 if (new_format.get_signed() and not min_format.get_signed()) \
        else 0
    return (new_format.get_integer_size() - sign_bias) >= \
        min_format.get_integer_size() and \
        new_format.get_frac_size() >= min_format.get_frac_size() and \
           (new_format.get_signed() or not min_format.get_signed())
Beispiel #14
0
def generate_bitfield_extraction(target_format, input_node, lo_index,
                                 hi_index):
    shift = lo_index
    mask_size = hi_index - lo_index + 1

    input_format = input_node.get_precision().get_base_format()
    if is_fixed_point(input_format) and is_fixed_point(target_format):
        frac_size = target_format.get_frac_size()
        int_size = input_format.get_bit_size() - frac_size
        cast_format = ML_Custom_FixedPoint_Format(int_size,
                                                  frac_size,
                                                  signed=False)
    else:
        cast_format = None

    # 1st step: shifting the input node the right amount
    shifted_node = input_node if shift == 0 else BitLogicRightShift(
        input_node,
        Constant(shift, precision=ML_Int32),
        precision=input_format)
    raw_format = ML_Custom_FixedPoint_Format(input_format.get_bit_size(),
                                             0,
                                             signed=False)
    # 2nd step: masking the input node
    # TODO/FIXME: check thast mask does not overflow or wrap-around
    masked_node = BitLogicAnd(TypeCast(shifted_node, precision=raw_format),
                              Constant((2**mask_size - 1),
                                       precision=raw_format),
                              precision=raw_format)

    if not cast_format is None:
        casted_node = TypeCast(masked_node, precision=cast_format)
    else:
        casted_node = masked_node

    converted_node = Conversion(casted_node, precision=target_format)
    return converted_node
def largest_format(format0, format1):
    if is_fixed_point(format0) and is_fixed_point(format1):
        #
        unsigned_int_size = format0.get_integer_size() if format1.get_signed() \
                            else format1.get_integer_size()
        signed_int_size = format1.get_integer_size() if format1.get_signed() \
                            else format0.get_integer_size()
        xor_signed = (format0.get_signed() != format1.get_signed()) and \
                    (unsigned_int_size >= signed_int_size)
        int_size = max(format0.get_integer_size(),
                       format1.get_integer_size()) + (1 if xor_signed else 0)
        frac_size = max(format0.get_frac_size(), format1.get_frac_size())
        return fixed_point(int_size,
                           frac_size,
                           signed=format0.get_signed() or format1.get_signed())
    elif format0 is None or format0 is ML_Integer:  # TODO: fix for abstract format
        return format1
    elif format1 is None or format1 is ML_Integer:  # TODO: fix for abstract format
        return format0
    elif format0.get_bit_size() == format1.get_bit_size():
        return format0
    else:
        Log.report(Log.Error, "unable to determine largest format")
        raise NotImplementedError
Beispiel #16
0
def solve_format_SubSignalSelection(optree):
    """ Dummy legalization of SubSignalSelection operation node """
    if optree.get_precision() is None:
        select_input = optree.get_input(0)
        input_prec = select_input.get_precision()

        inf_index = evaluate_cst_graph(optree.get_inf_index(),
                                       input_prec_solver=solve_format_rec)
        sup_index = evaluate_cst_graph(optree.get_sup_index(),
                                       input_prec_solver=solve_format_rec)

        if is_fixed_point(input_prec):
            frac_size = input_prec.get_frac_size() - inf_index
            integer_size = input_prec.get_integer_size() - (
                input_prec.get_bit_size() - 1 - sup_index)
            return fixed_point(integer_size, frac_size)
        else:
            return ML_StdLogicVectorFormat(sup_index - inf_index + 1)

    else:
        return optree.get_precision()