Ejemplo n.º 1
0
def convert_module_to_package(
    module: ast.Module,
    type_info: type_info_mod.TypeInfo,
    emit_positions: bool = True,
    traverse_tests: bool = False) -> ir_package.Package:
  """Converts the contents of a module to IR form.

  Args:
    module: Module to convert.
    type_info: Concrete type information used in conversion.
    emit_positions: Whether to emit positional metadata into the output IR.
    traverse_tests: Whether to convert functions called in DSLX test constructs.
      Note that this does NOT convert the test constructs themselves.

  Returns:
    The IR package that corresponds to this module.
  """
  emitted = []  # type: List[Text]
  package = ir_package.Package(module.name)
  order = extract_conversion_order.get_order(module, type_info,
                                             type_info.get_imports(),
                                             traverse_tests)
  logging.vlog(3, 'Convert order: %s', pprint.pformat(order))
  for record in order:
    emitted.append(
        _convert_one_function(
            package,
            record.m,
            record.f,
            record.type_info,
            symbolic_bindings=record.bindings,
            emit_positions=emit_positions))

  verifier_mod.verify_package(package)
  return package
Ejemplo n.º 2
0
    def test_invoke_adder_2_plus_3_eq_5(self):
        p = ir_package.Package('test_package')
        fb = function_builder.FunctionBuilder('add_wrapper', p)
        t = p.get_bits_type(32)
        x = fb.add_param('x', t)
        y = fb.add_param('y', t)
        fb.add_add(x, y)
        add_wrapper = fb.build()

        main_fb = function_builder.FunctionBuilder('main', p)
        two = main_fb.add_literal_bits(bits_mod.UBits(value=2, bit_count=32))
        three = main_fb.add_literal_bits(bits_mod.UBits(value=3, bit_count=32))
        observed = main_fb.add_invoke([two, three], add_wrapper)
        main_fb.add_eq(
            observed,
            main_fb.add_literal_bits(bits_mod.UBits(value=5, bit_count=32)))
        main_fb.build()
        self.assertMultiLineEqual(
            p.dump_ir(), """\
package test_package

fn add_wrapper(x: bits[32], y: bits[32]) -> bits[32] {
  ret add.3: bits[32] = add(x, y, id=3)
}

fn main() -> bits[1] {
  literal.4: bits[32] = literal(value=2, id=4)
  literal.5: bits[32] = literal(value=3, id=5)
  invoke.6: bits[32] = invoke(literal.4, literal.5, to_apply=add_wrapper, id=6)
  literal.7: bits[32] = literal(value=5, id=7)
  ret eq.8: bits[1] = eq(invoke.6, literal.7, id=8)
}
""")
Ejemplo n.º 3
0
 def test_generates_sources(self):
   p = package.Package('the_package')
   ir_text, netlist_text = self.lc._generate_sources(
       op_pb2.OpProto.OP_ADD,
       [p.get_bits_type(8), p.get_bits_type(8)], p.get_bits_type(8))
   self.assertIn('ret add.1: bits[8]', ir_text)
   self.assertEqual(netlist_text, '// NETLIST')
Ejemplo n.º 4
0
    def test_array_type(self):
        pkg = package.Package('pkg')
        bit_type = pkg.get_bits_type(4)
        t = pkg.get_array_type(3, bit_type)

        self.assertEqual(3, t.get_size())
        self.assertEqual(4, t.get_element_type().get_bit_count())
Ejemplo n.º 5
0
  def test_simple_build_and_dump_package(self):
    p = ir_package.Package('test_package')
    fileno = p.get_or_create_fileno('my_file.x')
    fb = function_builder.FunctionBuilder('test_function', p)
    t = p.get_bits_type(32)
    x = fb.add_param('x', t)

    lineno = fileno_mod.Lineno(42)
    colno = fileno_mod.Colno(64)
    loc = source_location.SourceLocation(fileno, lineno, colno)
    fb.add_or(x, x, loc=loc, name='my_or')
    fb.add_not(x, loc=loc, name='why_not')

    f = fb.build()
    self.assertEqual(f.name, 'test_function')
    self.assertEqual(
        f.dump_ir(), """\
fn test_function(x: bits[32]) -> bits[32] {
  my_or: bits[32] = or(x, x, id=2, pos=0,42,64)
  ret why_not: bits[32] = not(x, id=3, pos=0,42,64)
}
""")

    self.assertMultiLineEqual(
        p.dump_ir(), """\
package test_package

fn test_function(x: bits[32]) -> bits[32] {
  my_or: bits[32] = or(x, x, id=2, pos=0,42,64)
  ret why_not: bits[32] = not(x, id=3, pos=0,42,64)
}
""")
Ejemplo n.º 6
0
  def test_lec_smoke(self):
    p = package.Package('the_package')

    temp_dir = tempfile.TemporaryDirectory()
    results_path = os.path.join(temp_dir.name, 'results.textproto')

    num_iters = 16

    byte_type = p.get_bits_type(8)
    self.lc.run(
        op=op_pb2.OpProto.OP_ADD,
        samples=[([byte_type, byte_type], byte_type)],
        num_iters=num_iters,
        cell_library_textproto=self.cell_lib_text,
        results_path=results_path,
        lec_fn=lambda a, b, c, d: True)

    # Open results, verify contents
    results = lec_characterizer_pb2.LecTiming()
    with gfile.open(results_path, 'r') as f:
      text_format.Parse(f.read(), results)

    self.assertEqual(results.ir_function, 'single_op_OP_ADD')
    self.assertLen(results.test_cases, 1)
    test_case = results.test_cases[0]
    self.assertLen(test_case.exec_times_us, num_iters)
Ejemplo n.º 7
0
    def test_standard_pipeline(self):
        pkg = package.Package('pname')
        fb = function_builder.FunctionBuilder('main', pkg)
        fb.add_literal_bits(bits_mod.UBits(value=2, bit_count=32))
        fb.build()

        self.assertFalse(standard_pipeline.run_standard_pass_pipeline(pkg))
Ejemplo n.º 8
0
    def test_verify_function(self):
        pkg = package.Package('pname')
        builder = function_builder.FunctionBuilder('f_name', pkg)
        builder.add_param('x', pkg.get_bits_type(32))
        builder.add_literal_value(ir_value.Value(bits.UBits(7, 8)))
        fn = builder.build()

        verifier.verify_function(fn)
Ejemplo n.º 9
0
  def test_read_then_write(self):
    p = package.Package('the_package')

    temp_dir = tempfile.TemporaryDirectory()
    results_path = os.path.join(temp_dir.name, 'results.textproto')
    results = lec_characterizer_pb2.LecTiming()
    results.ir_function = 'single_op_OP_ADD'

    # Add one un-touched test case, and add one that should be appended to.
    proto_byte = xls_type_pb2.TypeProto()
    proto_byte.type_enum = xls_type_pb2.TypeProto.BITS
    proto_byte.bit_count = 8
    proto_short = xls_type_pb2.TypeProto()
    proto_short.type_enum = xls_type_pb2.TypeProto.BITS
    proto_short.bit_count = 16

    test_case = results.test_cases.add()
    param = test_case.function_type.parameters.add()
    param.CopyFrom(proto_short)
    param = test_case.function_type.parameters.add()
    param.CopyFrom(proto_short)
    test_case.function_type.return_type.CopyFrom(proto_short)

    test_case = results.test_cases.add()
    param = test_case.function_type.parameters.add()
    param.CopyFrom(proto_byte)
    param = test_case.function_type.parameters.add()
    param.CopyFrom(proto_byte)
    test_case.function_type.return_type.CopyFrom(proto_byte)
    test_case.exec_times_us.extend([1, 3, 7])
    test_case.average_us = 3

    with gfile.open(results_path, 'w') as f:
      f.write(text_format.MessageToString(results))

    num_iters = 16
    byte_type = p.get_bits_type(8)
    self.lc.run(
        op=op_pb2.OpProto.OP_ADD,
        samples=[([byte_type, byte_type], byte_type)],
        num_iters=num_iters,
        cell_library_textproto=self.cell_lib_text,
        results_path=results_path,
        lec_fn=lambda a, b, c, d: True)

    results = lec_characterizer_pb2.LecTiming()
    with gfile.open(results_path, 'r') as f:
      text_format.Parse(f.read(), results)

    self.assertEqual(results.ir_function, 'single_op_OP_ADD')
    self.assertLen(results.test_cases, 2)
    for test_case in results.test_cases:
      if test_case.function_type.return_type.bit_count == 16:
        self.assertEmpty(test_case.exec_times_us)
      else:
        self.assertLen(test_case.exec_times_us, 3 + num_iters)
Ejemplo n.º 10
0
    def test_bvalue_methods(self):
        # This test is mainly about checking that pybind11 is able to map parameter
        # and return types properly. Because of this it's not necessary to check
        # the result at the end; that methods don't throw when called is enough.
        p = ir_package.Package('test_package')
        fb = function_builder.FunctionBuilder('test_function', p)
        x = fb.add_param('param_name', p.get_bits_type(32))

        self.assertIn('param_name', str(x))
        self.assertEqual(32, x.get_type().get_bit_count())
Ejemplo n.º 11
0
    def test_pipeline_generator_with_clock_period(self):
        pkg = package.Package('pname')
        fb = function_builder.FunctionBuilder('main', pkg)
        fb.add_param('x', pkg.get_bits_type(32))
        fb.build()

        module_signature = pipeline_generator.generate_pipelined_module_with_clock_period(
            pkg, 100, 'bar')

        self.assertIn('module bar', module_signature.verilog_text)
        self.assertIn('p0_x', module_signature.verilog_text)
        self.assertIn('p1_x', module_signature.verilog_text)
Ejemplo n.º 12
0
  def test_generates_sources(self):
    server_path = runfiles.get_path('xls/synthesis/dummy_synthesis_server_main')

    port = portpicker.pick_unused_port()
    lc = lec_characterizer.LecCharacterizer(
        [server_path, '--port={}'.format(port)], port)
    p = package.Package('the_package')
    ir_text, netlist_text = lc._generate_sources(
        op_pb2.OpProto.OP_ADD,
        [p.get_bits_type(8), p.get_bits_type(8)], p.get_bits_type(8))
    self.assertIn('ret add.1: bits[8]', ir_text)
    self.assertEqual(netlist_text, '// NETLIST')
Ejemplo n.º 13
0
  def test_parse_value(self):
    p = package_mod.Package('test_package')
    u32 = p.get_bits_type(32)
    u8 = p.get_bits_type(8)
    t = p.get_tuple_type([u32, u8])
    s = '({}, {})'.format(0xdeadbeef, 0xcd)
    v = ir_parser.Parser.parse_value(s, t)
    self.assertEqual(s, str(v))

    v = ir_parser.Parser.parse_value('(0xdeadbeef, 0xcd)', t)
    self.assertEqual('(bits[32]:{}, bits[8]:{})'.format(0xdeadbeef, 0xcd),
                     v.to_str())
Ejemplo n.º 14
0
    def test_function_type(self):
        pkg = package.Package('pname')
        builder = function_builder.FunctionBuilder('f_name', pkg)
        builder.add_param('x', pkg.get_bits_type(32))
        builder.add_literal_value(ir_value.Value(bits.UBits(7, 8)))
        fn = builder.build()
        fn_type = fn.get_type()

        self.assertIsInstance(fn_type, ir_type.FunctionType)
        self.assertIn('bits[32]', str(fn_type))
        self.assertEqual(8, fn_type.return_type().get_bit_count())
        self.assertEqual(1, fn_type.get_parameter_count())
        self.assertEqual(32, fn_type.get_parameter_type(0).get_bit_count())
Ejemplo n.º 15
0
def convert_one_function(module: ast.Module,
                         entry_function_name: Text,
                         type_info: type_info_mod.TypeInfo,
                         emit_positions: bool = True) -> Text:
  """Returns function named entry_function_name in module as IR text."""
  package = ir_package.Package(module.name)
  _convert_one_function(
      package,
      module,
      module.get_function(entry_function_name),
      type_info,
      emit_positions=emit_positions)
  return package.dump_ir()
Ejemplo n.º 16
0
    def test_pipeline_generator_with_n_stages(self):
        pkg = package.Package('pname')
        fb = function_builder.FunctionBuilder('main', pkg)
        fb.add_param('x', pkg.get_bits_type(32))
        fb.build()

        module_signature = pipeline_generator.generate_pipelined_module_with_n_stages(
            pkg, 5, 'foo')

        self.assertIn('module foo', module_signature.verilog_text)
        self.assertIn('p0_x', module_signature.verilog_text)
        self.assertIn('p1_x', module_signature.verilog_text)
        self.assertIn('p2_x', module_signature.verilog_text)
        self.assertIn('p3_x', module_signature.verilog_text)
        self.assertIn('p4_x', module_signature.verilog_text)
Ejemplo n.º 17
0
    def test_package_methods(self):
        pkg = package.Package('pkg')
        fb = function_builder.FunctionBuilder('f', pkg)
        fb.add_literal_value(ir_value.Value(bits.UBits(7, 8)))
        fb.build()

        self.assertIn('pkg', pkg.dump_ir())
        self.assertIsInstance(pkg.get_bits_type(4), ir_type.BitsType)
        self.assertIsInstance(pkg.get_array_type(4, pkg.get_bits_type(4)),
                              ir_type.ArrayType)
        self.assertIsInstance(pkg.get_tuple_type([pkg.get_bits_type(4)]),
                              ir_type.TupleType)
        self.assertIsInstance(pkg.get_or_create_fileno('file'), fileno.Fileno)
        self.assertIsInstance(pkg.get_function('f'), function.Function)
        self.assertEqual(['f'], pkg.get_function_names())
Ejemplo n.º 18
0
    def test_literal_array(self):
        p = ir_package.Package('test_package')
        fb = function_builder.FunctionBuilder('f', p)
        fb.add_literal_value(
            ir_value.Value.make_array([
                ir_value.Value(bits_mod.UBits(value=5, bit_count=32)),
                ir_value.Value(bits_mod.UBits(value=6, bit_count=32)),
            ]))
        fb.build()
        self.assertMultiLineEqual(
            p.dump_ir(), """\
package test_package

fn f() -> bits[32][2] {
  ret literal.1: bits[32][2] = literal(value=[5, 6], id=1)
}
""")
Ejemplo n.º 19
0
    def test_type_polymorphism(self):
        # Verify that pybind11 knows to down-cast Type objects.

        pkg = package.Package('pkg')
        bits_type = pkg.get_bits_type(4)
        array_type = pkg.get_array_type(3, bits_type)
        tuple_type = pkg.get_tuple_type([bits_type])

        self.assertIsInstance(
            pkg.get_array_type(1, bits_type).get_element_type(),
            ir_type.BitsType)
        self.assertIsInstance(
            pkg.get_array_type(1, array_type).get_element_type(),
            ir_type.ArrayType)
        self.assertIsInstance(
            pkg.get_array_type(1, tuple_type).get_element_type(),
            ir_type.TupleType)
Ejemplo n.º 20
0
    def test_match_true(self):
        p = ir_package.Package('test_package')
        fb = function_builder.FunctionBuilder('f', p)
        pred_t = p.get_bits_type(1)
        expr_t = p.get_bits_type(32)
        pred_x = fb.add_param('pred_x', pred_t)
        x = fb.add_param('x', expr_t)
        pred_y = fb.add_param('pred_y', pred_t)
        y = fb.add_param('y', expr_t)
        default = fb.add_param('default', expr_t)
        fb.add_match_true([pred_x, pred_y], [x, y], default)
        fb.build()
        self.assertMultiLineEqual(
            p.dump_ir(), """\
package test_package

fn f(pred_x: bits[1], x: bits[32], pred_y: bits[1], y: bits[32], default: bits[32]) -> bits[32] {
  concat.6: bits[2] = concat(pred_y, pred_x, id=6)
  one_hot.7: bits[3] = one_hot(concat.6, lsb_prio=true, id=7)
  ret one_hot_sel.8: bits[32] = one_hot_sel(one_hot.7, cases=[x, y, default], id=8)
}
""")
Ejemplo n.º 21
0
 def test_verify_package(self):
     pkg = package.Package('pkg')
     verifier.verify_package(pkg)
Ejemplo n.º 22
0
    def test_type(self):
        pkg = package.Package('pkg')
        t = pkg.get_bits_type(4)

        self.assertIn('4', str(t))
Ejemplo n.º 23
0
    def test_bits_type(self):
        pkg = package.Package('pkg')
        t = pkg.get_bits_type(4)

        self.assertEqual(4, t.get_bit_count())
Ejemplo n.º 24
0
    def test_all_add_methods(self):
        # This test is mainly about checking that pybind11 is able to map parameter
        # and return types properly. Because of this it's not necessary to check
        # the result at the end; that methods don't throw when called is enough.
        p = ir_package.Package('test_package')
        fileno = p.get_or_create_fileno('my_file.x')
        lineno = fileno_mod.Lineno(42)
        colno = fileno_mod.Colno(64)
        loc = source_location.SourceLocation(fileno, lineno, colno)
        fb = function_builder.FunctionBuilder('test_function', p)

        input_function_builder = function_builder.FunctionBuilder('fn', p)
        input_function_builder.add_literal_value(
            ir_value.Value(bits_mod.UBits(7, 8)))
        input_function = input_function_builder.build()

        single_zero_bit = fb.add_literal_value(
            ir_value.Value(bits_mod.UBits(value=0, bit_count=1)))
        t = p.get_bits_type(32)
        x = fb.add_param('x', t)

        fb.add_shra(x, x, loc=loc)
        fb.add_shra(x, x, loc=loc)
        fb.add_shrl(x, x, loc=loc)
        fb.add_shll(x, x, loc=loc)
        fb.add_or(x, x, loc=loc)
        fb.add_nary_or([x], loc=loc)
        fb.add_xor(x, x, loc=loc)
        fb.add_and(x, x, loc=loc)
        fb.add_smul(x, x, loc=loc)
        fb.add_umul(x, x, loc=loc)
        fb.add_udiv(x, x, loc=loc)
        fb.add_sub(x, x, loc=loc)
        fb.add_add(x, x, loc=loc)

        fb.add_concat([x], loc=loc)

        fb.add_ule(x, x, loc=loc)
        fb.add_ult(x, x, loc=loc)
        fb.add_uge(x, x, loc=loc)
        fb.add_ugt(x, x, loc=loc)

        fb.add_sle(x, x, loc=loc)
        fb.add_slt(x, x, loc=loc)
        fb.add_sge(x, x, loc=loc)
        fb.add_sgt(x, x, loc=loc)

        fb.add_eq(x, x, loc=loc)
        fb.add_ne(x, x, loc=loc)

        fb.add_neg(x, loc=loc)
        fb.add_not(x, loc=loc)
        fb.add_clz(x, loc=loc)

        fb.add_one_hot(x, lsb_or_msb.LsbOrMsb.LSB, loc=loc)
        fb.add_one_hot_sel(x, [x], loc=loc)

        fb.add_literal_bits(bits_mod.UBits(value=2, bit_count=32), loc=loc)
        fb.add_literal_value(ir_value.Value(
            bits_mod.UBits(value=5, bit_count=32)),
                             loc=loc)

        fb.add_sel(x, x, x, loc=loc)
        fb.add_sel_multi(x, [x], x, loc=loc)
        fb.add_match_true([single_zero_bit], [x], x, loc=loc)

        tuple_node = fb.add_tuple([x], loc=loc)
        fb.add_array([x], t, loc=loc)

        fb.add_tuple_index(tuple_node, 0, loc=loc)

        fb.add_counted_for(x, 1, 1, input_function, [x], loc=loc)

        fb.add_map(fb.add_array([x], t, loc=loc), input_function, loc=loc)

        fb.add_invoke([x], input_function, loc=loc)

        fb.add_array_index(fb.add_array([x], t, loc=loc), x, loc=loc)
        fb.add_reverse(fb.add_array([x], t, loc=loc), loc=loc)
        fb.add_identity(x, loc=loc)
        fb.add_signext(x, 10, loc=loc)
        fb.add_zeroext(x, 10, loc=loc)
        fb.add_bit_slice(x, 4, 2, loc=loc)

        fb.build()
Ejemplo n.º 25
0
def build_function(name='function_name'):
    pkg = package.Package('pname')
    builder = function_builder.FunctionBuilder(name, pkg)
    builder.add_literal_value(value.Value(bits.UBits(7, 8)))
    return builder.build()