Exemplo n.º 1
0
def mantissa_extraction_modifier_from_fields(op,
                                             field_op,
                                             exp_is_zero,
                                             tag="mant_extr"):
    """ Legalizing a MantissaExtraction node into a sub-graph
        of basic operation, assuming <field_op> bitfield and <exp_is_zero> flag
        are already available """

    op_precision = op.get_precision().get_base_format()

    implicit_digit = Select(
        exp_is_zero,
        Constant(0, precision=ML_StdLogic),
        Constant(1, precision=ML_StdLogic),
        precision=ML_StdLogic,
        tag=tag + "_implicit_digit",
    )
    result = Concatenation(
        implicit_digit,
        TypeCast(field_op,
                 precision=ML_StdLogicVectorFormat(
                     op_precision.get_field_size())),
        precision=ML_StdLogicVectorFormat(op_precision.get_mantissa_size()),
    )
    return result
Exemplo n.º 2
0
def legalize_fixed_point_subselection(optree,
                                      input_prec_solver=default_prec_solver):
    """ Legalize a SubSignalSelection on a fixed-point node """
    sub_input = optree.get_input(0)
    inf_index = evaluate_cst_graph(optree.get_inf_index(),
                                   input_prec_solver=input_prec_solver)
    sup_index = evaluate_cst_graph(optree.get_sup_index(),
                                   input_prec_solver=input_prec_solver)
    assert not inf_index is None and not sup_index is None
    input_format = ML_StdLogicVectorFormat(
        sub_input.get_precision().get_bit_size())
    output_format = ML_StdLogicVectorFormat(sup_index - inf_index + 1)
    subselect = SubSignalSelection(TypeCast(sub_input, precision=input_format),
                                   inf_index,
                                   sup_index,
                                   precision=output_format)
    result = TypeCast(
        subselect,
        precision=optree.get_precision(),
    )
    # TypeCast may be simplified during code generation so attributes
    # may also be forwarded to previous node
    forward_attributes(optree, subselect)
    forward_attributes(optree, result)
    return result
Exemplo n.º 3
0
def get_output_check_statement(output_signal, output_tag, output_value):
    """ Generate output value check statement """
    test_pass_cond = Comparison(
        output_signal,
        output_value,
        specifier=Comparison.Equal,
        precision=ML_Bool
    )

    check_statement = ConditionBlock(
        LogicalNot(
            test_pass_cond,
            precision = ML_Bool
        ),
        Report(
            Concatenation(
                " result for {}: ".format(output_tag),
                Conversion(
                    output_signal if output_signal.get_precision() is ML_StdLogic else
                    TypeCast(
                        output_signal,
                        precision=ML_StdLogicVectorFormat(
                            output_signal.get_precision().get_bit_size()
                        )
                     ),
                    precision = ML_String
                    ),
                precision = ML_String
            )
        )
    )
    return test_pass_cond, check_statement
Exemplo n.º 4
0
    def generate_scheme(self):
        """ main scheme generation """
        Log.report(Log.Info, "input_precision is {}".format(self.input_precision))
        Log.report(Log.Info, "output_precision is {}".format(self.output_precision))

        # generating component instantiation before meta-entity scheme
        lzc_in_width = self.input_precision.get_bit_size()
        lzc_implementation = self.generate_sub_lzc_component(lzc_in_width)
        lzc_component = lzc_implementation.get_component_object()

        # declaring main input variable
        var_x = self.implementation.add_input_signal("x", self.input_precision)
        var_x.set_attributes(debug = debug_fixed)


        lzc_out_width = ML_LeadingZeroCounter.get_lzc_output_width(lzc_in_width)
        lzc_out_format = ML_StdLogicVectorFormat(lzc_out_width)

        # input
        lzc_in = var_x
        var_x_lzc = Signal(
            "var_x_lzc", precision=lzc_out_format, var_type=Signal.Local, debug=debug_dec)
        var_x_lzc = PlaceHolder(var_x_lzc, lzc_component(io_map={"x": lzc_in, "vr_out": var_x_lzc}))

        # output
        self.implementation.add_output_signal("vr_out", var_x_lzc)

        return [self.implementation, lzc_implementation]
Exemplo n.º 5
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()
Exemplo n.º 6
0
def raw_fp_field_extraction(optree):
    """ generate an operation sub-graph to extract the fp field
        (mantissa without implicit digit) of a fp node """
    size = optree.get_precision().get_base_format().get_bit_size()
    field_size = optree.get_precision().get_base_format().get_field_size()
    return TypeCast(SubSignalSelection(
        TypeCast(optree, precision=ML_StdLogicVectorFormat(size)), 0,
        field_size - 1),
                    precision=fixed_point(field_size, 0, signed=False))
Exemplo n.º 7
0
def signal_str_conversion(optree, op_format):
    """ converision of @p optree from op_format to ML_String """
    return Conversion(
        optree if op_format is ML_StdLogic else
        TypeCast(
            optree,
            precision=ML_StdLogicVectorFormat(
                op_format.get_bit_size()
            )
         ),
        precision=ML_String
    )
Exemplo n.º 8
0
def mantissa_extraction_modifier(optree):
    """ Legalizing a MantissaExtraction node into a sub-graph
        of basic operation """
    init_stage = optree.attributes.get_dyn_attribute("init_stage")
    op = optree.get_input(0)
    tag = optree.get_tag() or "mant_extr"

    op_precision = op.get_precision().get_base_format()
    exp_prec = ML_StdLogicVectorFormat(op_precision.get_exponent_size())
    field_prec = ML_StdLogicVectorFormat(op_precision.get_field_size())

    exp_op = RawExponentExtraction(op,
                                   precision=exp_prec,
                                   init_stage=init_stage,
                                   tag=tag + "_exp_extr")
    field_op = SubSignalSelection(TypeCast(
        op,
        precision=op.get_precision().get_support_format(),
        init_stage=init_stage,
        tag=tag + "_field_cast"),
                                  0,
                                  op_precision.get_field_size() - 1,
                                  precision=field_prec,
                                  init_stage=init_stage,
                                  tag=tag + "_field")
    exp_is_zero = Comparison(exp_op,
                             Constant(op_precision.get_zero_exponent_value(),
                                      precision=exp_prec,
                                      init_stage=init_stage),
                             precision=ML_Bool,
                             specifier=Comparison.Equal,
                             init_stage=init_stage)

    result = mantissa_extraction_modifier_from_fields(op, field_op,
                                                      exp_is_zero)
    forward_attributes(optree, result)
    return result
Exemplo n.º 9
0
def vector_concatenation(*args):
    """ Concatenate a list of signals of arbitrary length into
        a single ML_StdLogicVectorFormat node whose correct precision set """
    num_args = len(args)
    if num_args == 1:
        return args[0]
    else:
        half_num = int(num_args / 2)
        lhs = vector_concatenation(*args[:half_num])
        rhs = vector_concatenation(*args[half_num:])
        return Concatenation(lhs,
                             rhs,
                             precision=ML_StdLogicVectorFormat(
                                 lhs.get_precision().get_bit_size() +
                                 rhs.get_precision().get_bit_size()))
Exemplo n.º 10
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()
Exemplo n.º 11
0
def comp_3to2(a, b, c):
    """ 3 digits to 2 digits compressor """
    s = BitLogicXor(a,
                    BitLogicXor(b, c, precision=ML_StdLogic),
                    precision=ML_StdLogic)
    c = BitLogicOr(BitLogicAnd(a, b, precision=ML_StdLogic),
                   BitLogicOr(BitLogicAnd(a, c, precision=ML_StdLogic),
                              BitLogicAnd(c, b, precision=ML_StdLogic),
                              precision=ML_StdLogic),
                   precision=ML_StdLogic)
    return c, s

    a = TypeCast(a, precision=fixed_point(1, 0, signed=False))
    b = TypeCast(b, precision=fixed_point(1, 0, signed=False))
    c = TypeCast(c, precision=fixed_point(1, 0, signed=False))

    full = TypeCast(Conversion(a + b + c,
                               precision=fixed_point(2, 0, signed=False)),
                    precision=ML_StdLogicVectorFormat(2))
    carry = BitSelection(full, 1)
    digit = BitSelection(full, 0)
    return carry, digit
Exemplo n.º 12
0
    def generate_scheme(self):
        """ generate main architecture for UT_RTL_Report """

        main = Statement()
        # basic string
        main.add(Report("displaying simple string"))
        # string from std_logic_vector conversion
        cst_format = ML_StdLogicVectorFormat(12)
        cst = Constant(17, precision=cst_format)
        main.add(Report(Conversion(cst, precision=ML_String)))
        # string from concatenation of several elements
        complex_string = Concatenation("displaying concatenated string",
                                       Conversion(cst, precision=ML_String),
                                       precision=ML_String)
        main.add(Report(complex_string))

        main.add(Wait(100))

        # main process
        main_process = Process(main)
        self.implementation.add_process(main_process)

        return [self.implementation]
Exemplo n.º 13
0
def convert_bit_heap_to_fixed_point(current_bit_heap, signed=False):
    # final propagating sum
    op_index = 0
    op_list = []
    op_statement = Statement()
    while current_bit_heap.max_count() > 0:
        op_size = current_bit_heap.max_index - current_bit_heap.min_index + 1
        op_format = ML_StdLogicVectorFormat(op_size)
        op_reduce = Signal("op_%d" % op_index,
                           precision=op_format,
                           var_type=Variable.Local)

        offset_index = current_bit_heap.min_index

        for index in range(current_bit_heap.min_index,
                           current_bit_heap.max_index + 1):
            out_index = index - offset_index
            bit_list = current_bit_heap.pop_bits(index, 1)
            if len(bit_list) == 0:
                op_statement.push(
                    ReferenceAssign(BitSelection(op_reduce, out_index),
                                    Constant(0, precision=ML_StdLogic)))
            else:
                assert len(bit_list) == 1
                op_statement.push(
                    ReferenceAssign(BitSelection(op_reduce, out_index),
                                    bit_list[0]))

        op_precision = fixed_point(op_size + offset_index,
                                   -offset_index,
                                   signed=signed)
        op_list.append(
            PlaceHolder(TypeCast(op_reduce, precision=op_precision),
                        op_statement))
        op_index += 1
    return op_list, op_statement
Exemplo n.º 14
0
    def generate_auto_test(self,
                           test_num=10,
                           test_range=Interval(-1.0, 1.0),
                           debug=False,
                           time_step=10):
        """ time_step: duration of a stage (in ns) """
        # instanciating tested component
        # map of input_tag -> input_signal and output_tag -> output_signal
        io_map = {}
        # map of input_tag -> input_signal, excludind commodity signals
        # (e.g. clock and reset)
        input_signals = {}
        # map of output_tag -> output_signal
        output_signals = {}
        # excluding clock and reset signals from argument list
        # reduced_arg_list = [input_port for input_port in self.implementation.get_arg_list() if not input_port.get_tag() in ["clk", "reset"]]
        reduced_arg_list = self.implementation.get_arg_list()
        for input_port in reduced_arg_list:
            input_tag = input_port.get_tag()
            input_signal = Signal(input_tag + "_i",
                                  precision=input_port.get_precision(),
                                  var_type=Signal.Local)
            io_map[input_tag] = input_signal
            if not input_tag in ["clk", "reset"]:
                input_signals[input_tag] = input_signal
        for output_port in self.implementation.get_output_port():
            output_tag = output_port.get_tag()
            output_signal = Signal(output_tag + "_o",
                                   precision=output_port.get_precision(),
                                   var_type=Signal.Local)
            io_map[output_tag] = output_signal
            output_signals[output_tag] = output_signal

        # building list of test cases
        tc_list = []

        self_component = self.implementation.get_component_object()
        self_instance = self_component(io_map=io_map, tag="tested_entity")
        test_statement = Statement()

        # initializing random test case generator
        self.init_test_generator()

        # Appending standard test cases if required
        if self.auto_test_std:
            tc_list += self.standard_test_cases

        for i in range(test_num):
            input_values = self.generate_test_case(input_signals, io_map, i,
                                                   test_range)
            tc_list.append((input_values, None))

        def compute_results(tc):
            """ update test case with output values if required """
            input_values, output_values = tc
            if output_values is None:
                return input_values, self.numeric_emulate(input_values)
            else:
                return tc

        # filling output values
        tc_list = [compute_results(tc) for tc in tc_list]

        for input_values, output_values in tc_list:
            input_msg = ""

            # Adding input setting
            for input_tag in input_values:
                input_signal = io_map[input_tag]
                # FIXME: correct value generation depending on signal precision
                input_value = input_values[input_tag]
                test_statement.add(
                    ReferenceAssign(
                        input_signal,
                        Constant(input_value,
                                 precision=input_signal.get_precision())))
                value_msg = input_signal.get_precision().get_cst(
                    input_value, language=VHDL_Code).replace('"', "'")
                value_msg += " / " + hex(input_signal.get_precision(
                ).get_base_format().get_integer_coding(input_value))
                input_msg += " {}={} ".format(input_tag, value_msg)
            test_statement.add(Wait(time_step * self.stage_num))
            # Adding output value comparison
            for output_tag in output_signals:
                output_signal = output_signals[output_tag]
                output_value = Constant(
                    output_values[output_tag],
                    precision=output_signal.get_precision())
                output_precision = output_signal.get_precision()
                expected_dec = output_precision.get_cst(
                    output_values[output_tag],
                    language=VHDL_Code).replace('"', "'")
                expected_hex = " / " + hex(
                    output_precision.get_base_format().get_integer_coding(
                        output_values[output_tag]))
                value_msg = "{} / {}".format(expected_dec, expected_hex)

                test_pass_cond = Comparison(output_signal,
                                            output_value,
                                            specifier=Comparison.Equal,
                                            precision=ML_Bool)

                test_statement.add(
                    ConditionBlock(
                        LogicalNot(test_pass_cond, precision=ML_Bool),
                        Report(
                            Concatenation(
                                " result for {}: ".format(output_tag),
                                Conversion(TypeCast(
                                    output_signal,
                                    precision=ML_StdLogicVectorFormat(
                                        output_signal.get_precision(
                                        ).get_bit_size())),
                                           precision=ML_String),
                                precision=ML_String))))
                test_statement.add(
                    Assert(
                        test_pass_cond,
                        "\"unexpected value for inputs {input_msg}, output {output_tag}, expecting {value_msg}, got: \""
                        .format(input_msg=input_msg,
                                output_tag=output_tag,
                                value_msg=value_msg),
                        severity=Assert.Failure))

        testbench = CodeEntity("testbench")
        test_process = Process(
            test_statement,
            # end of test
            Assert(Constant(0, precision=ML_Bool),
                   " \"end of test, no error encountered \"",
                   severity=Assert.Failure))

        testbench_scheme = Statement(self_instance, test_process)

        if self.pipelined:
            half_time_step = time_step / 2
            assert (half_time_step * 2) == time_step
            # adding clock process for pipelined bench
            clk_process = Process(
                Statement(
                    ReferenceAssign(io_map["clk"],
                                    Constant(1, precision=ML_StdLogic)),
                    Wait(half_time_step),
                    ReferenceAssign(io_map["clk"],
                                    Constant(0, precision=ML_StdLogic)),
                    Wait(half_time_step),
                ))
            testbench_scheme.push(clk_process)

        testbench.add_process(testbench_scheme)

        return [testbench]
Exemplo n.º 15
0
def booth_radix4_multiply(lhs, rhs, pos_bit_heap, neg_bit_heap):
    """ Compute the multiplication @p lhs x @p rhs using radix 4 Booth
        recoding and drop the generated partial product in @p
        pos_bit_heap and @p neg_bit_heap based on their sign """
    # booth recoded partial product for n-th digit
    # is based on digit from n-1 to n+1
    #    (n+1) | (n) | (n-1) |  PP  |
    #    ------|-----|-------|------|
    #      0   |  0  |   0   |  +0  |
    #      0   |  0  |   1   |  +X  |
    #      0   |  1  |   0   |  +X  |
    #      0   |  1  |   1   |  +2x |
    #      1   |  0  |   0   |  -2X |
    #      1   |  0  |   1   |  -X  |
    #      1   |  1  |   0   |  -X  |
    #      1   |  1  |   1   |  +0  |
    #    ------|-----|-------|------|
    assert lhs.get_precision().get_bit_size() >= 2

    # lhs is the recoded operand
    # RECODING DIGITS
    # first recoded digit is padded right by 0
    first_digit = Concatenation(SubSignalSelection(
        lhs, 0, 1, precision=ML_StdLogicVectorFormat(2)),
                                Constant(0, precision=ML_StdLogic),
                                precision=ML_StdLogicVectorFormat(3),
                                debug=debug_std,
                                tag="booth_digit_0")
    digit_list = [(first_digit, 0)]

    for digit_index in range(2, lhs.get_precision().get_bit_size(), 2):
        if digit_index + 1 < lhs.get_precision().get_bit_size():
            # digits exist completely in lhs
            digit = SubSignalSelection(lhs,
                                       digit_index - 1,
                                       digit_index + 1,
                                       tag="booth_digit_%d" % digit_index,
                                       debug=debug_std)
        else:
            # MSB padding required
            sign_ext = Constant(0, precision=ML_StdLogic) if not (
                lhs.get_precision().get_signed()) else BitSelection(
                    lhs,
                    lhs.get_precision().get_bit_size() - 1)
            digit = Concatenation(sign_ext,
                                  SubSignalSelection(lhs, digit_index - 1,
                                                     digit_index),
                                  precision=ML_StdLogicVectorFormat(3),
                                  debug=debug_std,
                                  tag="booth_digit_%d" % digit_index)
        digit_list.append((digit, digit_index))
    # if lhs size is a mutiple of two and it is unsigned
    # than an extra digit must be generated to ensure a positive result
    if lhs.get_precision().get_bit_size() % 2 == 0 and not (
            lhs.get_precision().get_signed()):
        digit_index = lhs.get_precision().get_bit_size() - 1
        digit = Concatenation(Constant(0,
                                       precision=ML_StdLogicVectorFormat(2)),
                              BitSelection(lhs, digit_index),
                              precision=ML_StdLogicVectorFormat(3),
                              debug=debug_std,
                              tag="booth_digit_%d" % (digit_index + 1))
        digit_list.append((digit, digit_index + 1))

    def DCV(value):
        """ Digit Constante Value """
        return Constant(value, precision=ML_StdLogicVectorFormat(3))

    # PARTIAL PRODUCT GENERATION
    # Radix-4 booth recoding requires the following Partial Products
    # -2.rhs, -rhs, 0, rhs and 2.rhs
    # Negative PP are obtained by 1's complement of the value correctly shifted
    # adding a positive one to the LSB (inserted separately) and assuming
    # MSB digit has a negative weight
    for digit, index in digit_list:
        pp_zero = LogicalOr(Equal(digit, DCV(0), precision=ML_Bool),
                            Equal(digit, DCV(7), precision=ML_Bool),
                            precision=ML_Bool)
        pp_shifted = LogicalOr(Equal(digit, DCV(3), precision=ML_Bool),
                               Equal(digit, DCV(4), precision=ML_Bool),
                               precision=ML_Bool)
        # excluding zero case
        pp_neg_bit = BitSelection(digit, 2)
        pp_neg = equal_to(pp_neg_bit, 1)
        pp_neg_lsb_carryin = Select(LogicalAnd(pp_neg, LogicalNot(pp_zero)),
                                    Constant(1, precision=ML_StdLogic),
                                    Constant(0, precision=ML_StdLogic),
                                    tag="pp_%d_neg_lsb_carryin" % index,
                                    debug=debug_std)

        # LSB digit
        lsb_pp_digit = Select(pp_shifted,
                              Constant(0, precision=ML_StdLogic),
                              BitSelection(rhs, 0),
                              precision=ML_StdLogic)
        lsb_local_pp = Select(pp_zero,
                              Constant(0, precision=ML_StdLogic),
                              Select(pp_neg,
                                     BitLogicNegate(lsb_pp_digit),
                                     lsb_pp_digit,
                                     precision=ML_StdLogic),
                              debug=debug_std,
                              tag="lsb_local_pp_%d" % index,
                              precision=ML_StdLogic)
        pos_bit_heap.insert_bit(index, lsb_local_pp)
        pos_bit_heap.insert_bit(index, pp_neg_lsb_carryin)

        # other digits
        rhs_size = rhs.get_precision().get_bit_size()
        for k in range(1, rhs_size):
            pp_digit = Select(pp_shifted,
                              BitSelection(rhs, k - 1),
                              BitSelection(rhs, k),
                              precision=ML_StdLogic)
            local_pp = Select(pp_zero,
                              Constant(0, precision=ML_StdLogic),
                              Select(pp_neg,
                                     BitLogicNegate(pp_digit),
                                     pp_digit,
                                     precision=ML_StdLogic),
                              debug=debug_std,
                              tag="local_pp_%d_%d" % (index, k),
                              precision=ML_StdLogic)
            pos_bit_heap.insert_bit(index + k, local_pp)
        # MSB digit
        msb_pp_digit = pp_digit = Select(
            pp_shifted,
            BitSelection(rhs, rhs_size - 1),
            # TODO: fix for signed rhs
            Constant(0, precision=ML_StdLogic)
            if not (rhs.get_precision().get_signed()) else BitSelection(
                rhs, rhs_size - 1),
            precision=ML_StdLogic)
        msb_pp = Select(pp_zero,
                        Constant(0, precision=ML_StdLogic),
                        Select(pp_neg,
                               BitLogicNegate(msb_pp_digit),
                               msb_pp_digit,
                               precision=ML_StdLogic),
                        debug=debug_std,
                        tag="msb_pp_%d" % (index),
                        precision=ML_StdLogic)
        if rhs.get_precision().get_signed():
            neg_bit_heap.insert_bit(index + rhs_size, msb_pp)
        else:
            pos_bit_heap.insert_bit(index + rhs_size, msb_pp)
            # MSB negative digit,
            # 'rhs_size + index) is the position of the MSB digit of rhs shifted by 1
            # we add +1 to get to the sign position
            neg_bit_heap.insert_bit(index + rhs_size + 1, pp_neg_lsb_carryin)
Exemplo n.º 16
0
        def rec_add(op_x, op_y, level=0, lower_limit=1):
            print("calling rec_add")
            n_x = op_x.get_precision().get_bit_size()
            n_y = op_y.get_precision().get_bit_size()
            n = max(n_x, n_y)
            if n <= lower_limit:
                if n == 1:
                    # end of recursion
                    def LSB(op):
                        return BitSelection(op, 0)

                    bit_x = LSB(op_x)
                    bit_y = LSB(op_y)
                    return (
                        # add
                        Conversion(BitLogicXor(bit_x,
                                               bit_y,
                                               precision=ML_StdLogic),
                                   precision=ML_StdLogicVectorFormat(1)),
                        # add + 1
                        Conversion(BitLogicNegate(BitLogicXor(
                            bit_x, bit_y, precision=ML_StdLogic),
                                                  precision=ML_StdLogic),
                                   precision=ML_StdLogicVectorFormat(1)),
                        # generate
                        BitLogicAnd(bit_x, bit_y, precision=ML_StdLogic),
                        # propagate
                        BitLogicXor(bit_x, bit_y, precision=ML_StdLogic))
                else:
                    numeric_x = TypeCast(op_x,
                                         precision=fixed_point(n_x,
                                                               0,
                                                               signed=False))
                    numeric_y = TypeCast(op_y,
                                         precision=fixed_point(n_y,
                                                               0,
                                                               signed=False))
                    pre_add = numeric_x + numeric_y
                    pre_addp1 = pre_add + 1
                    add = SubSignalSelection(pre_add, 0, n - 1)
                    addp1 = SubSignalSelection(pre_addp1, 0, n - 1)
                    generate = BitSelection(pre_add, n)
                    # TODO/FIXME: padd when op_x's size does not match op_y' size
                    bitwise_xor = BitLogicXor(
                        op_x, op_y, precision=ML_StdLogicVectorFormat(n))
                    op_list = [BitSelection(bitwise_xor, i) for i in range(n)]
                    propagate = logical_reduce(op_list,
                                               op_ctor=BitLogicAnd,
                                               precision=ML_StdLogic)

                    return add, addp1, generate, propagate

            half_n = int(n / 2)

            def subdivide(op, split_index_list):
                """ subdivide op node in len(split_index_list) + 1 slices
                    [0 to split_index_list[0]],
                    [split_index_list[0] + 1: split_index_list[1]], .... """
                n = op.get_precision().get_bit_size()
                sub_list = []
                lo_index = 0
                hi_index = None
                for s in split_index_list:
                    if lo_index >= n:
                        break
                    hi_index = min(s, n - 1)
                    local_slice = SubSignalSelection(
                        op, lo_index, hi_index
                    )  #, precision=fixed_point(hi_index - lo_index + 1, 0, signed=False))
                    sub_list.append(local_slice)
                    # key invariant to allow adding multiple subdivision together:
                    # the LSB weight must be uniform
                    lo_index = s + 1
                if hi_index < n - 1:
                    local_slice = SubSignalSelection(op, lo_index, n - 1)
                    sub_list.append(local_slice)
                # padding list
                while len(sub_list) < len(split_index_list) + 1:
                    sub_list.append(Constant(0))
                return sub_list

            x_slices = subdivide(op_x, [half_n - 1])
            y_slices = subdivide(op_y, [half_n - 1])

            # list of (x + y), (x + y + 1), generate, propagate
            add_slices = [
                rec_add(sub_x, sub_y, level=level + 1, lower_limit=lower_limit)
                for sub_x, sub_y in zip(x_slices, y_slices)
            ]

            NUM_SLICES = len(add_slices)

            def tree_reduce(gen_list, prop_list):
                return LogicalOr(
                    gen_list[-1],
                    LogicalAnd(prop_list[-1],
                               tree_reduce(gen_list[:-1], prop_list[:-1])))

            add_list = [op[0] for op in add_slices]
            addp1_list = [op[1] for op in add_slices]
            generate_list = [op[2] for op in add_slices]
            propagate_list = [op[3] for op in add_slices]

            carry_propagate = [propagate_list[0]]
            carry_generate = [generate_list[0]]
            add_result = [add_list[0]]
            addp1_result = [addp1_list[0]]
            for i in range(1, NUM_SLICES):

                def sub_name(prefix, index):
                    return "%s_%d_%d" % (prefix, level, index)

                carry_propagate.append(
                    BitLogicAnd(propagate_list[i],
                                carry_propagate[i - 1],
                                tag=sub_name("carry_propagate", i),
                                precision=ML_StdLogic))
                carry_generate.append(
                    BitLogicOr(generate_list[i],
                               BitLogicAnd(propagate_list[i],
                                           carry_generate[i - 1],
                                           precision=ML_StdLogic),
                               tag=sub_name("carry_generate", i),
                               precision=ML_StdLogic))
                add_result.append(
                    Select(carry_generate[i - 1],
                           addp1_list[i],
                           add_list[i],
                           tag=sub_name("add_result", i),
                           precision=addp1_list[i].get_precision()))
                addp1_result.append(
                    Select(BitLogicOr(carry_propagate[i - 1],
                                      carry_generate[i - 1],
                                      precision=ML_StdLogic),
                           addp1_list[i],
                           add_list[i],
                           tag=sub_name("addp1_result", i),
                           precision=addp1_list[i].get_precision()))
            add_result_full = vector_concatenation(
                #Conversion(carry_generate[-1], precision=ML_StdLogicVectorFormat(1)),
                *tuple(add_result[::-1]))
            addp1_result_full = vector_concatenation(
                #Conversion(BitLogicOr(carry_generate[-1], carry_propagate[-1], precision=ML_StdLogic), precision=ML_StdLogicVectorFormat(1)),
                *tuple(addp1_result[::-1]))
            return add_result_full, addp1_result_full, carry_generate[
                -1], carry_propagate[-1]
Exemplo n.º 17
0
 def DCV(value):
     """ Digit Constante Value """
     return Constant(value, precision=ML_StdLogicVectorFormat(3))