コード例 #1
0
ファイル: ast_generator.py プロジェクト: masc-ucsc/xls
 def _generate_logical_binop(self,
                             env: Env) -> Tuple[ast.Binop, ast.TypeAnnotation]:
   """Generates a logical binary operation (e.g. and, xor, or)."""
   make_lhs, lhs_type = self._choose_env_value(env, self._not_tuple_or_array)
   make_rhs, rhs_type = self._choose_env_value(env, self._not_tuple_or_array)
   # Convert into one-bit numbers by checking whether lhs and rhs values are 0.
   lhs = ast.Binop(self.m, self.fake_span, ast.BinopKind.NE, make_lhs(),
                   self._make_number(0, lhs_type))
   rhs = ast.Binop(self.m, self.fake_span, ast.BinopKind.NE, make_rhs(),
                   self._make_number(0, rhs_type))
   # Pick some operation to do.
   op = self.rng.choice([ast.BinopKind.LOGICAL_AND, ast.BinopKind.LOGICAL_OR])
   return ast.Binop(self.m, self.fake_span, op, lhs,
                    rhs), self._make_type_annotation(False, 1)
コード例 #2
0
ファイル: ast_generator.py プロジェクト: mfkiwl/xls
    def _generate_concat(self,
                         env: Env) -> Tuple[ast.Expr, ast.TypeAnnotation]:
        """Returns a (potentially vacuous) concatenate operation of values in `env`.

    Args:
      env: Environment of values that can be selected from for concatenation.
    Note: the concat operation will not exceed the maximum bit width so the
      concat may end up being a nop.
    """
        if self._env_contains_array(env) and self.rng.choice([True, False]):
            return self._generate_array_concat(env)

        count = self._generate_nary_operand_count(env) + 2
        operands = []
        operand_types = []
        for i in range(count):
            make_arg, arg_type = self._choose_env_value(
                env, self._is_builtin_unsigned)
            operands.append(make_arg())
            operand_types.append(arg_type)
        result = operands[0]
        result_bits = builtin_type_to_bits(operand_types[0])
        for i in range(1, count):
            this_bits = builtin_type_to_bits(operand_types[i])
            if result_bits + this_bits > self.options.max_width_bits_types:
                break
            result = ast.Binop(self.m, self.fake_span, ast.BinopKind.CONCAT,
                               result, operands[i])
            result_bits += this_bits
        assert result_bits <= self.options.max_width_bits_types, result_bits
        return (result, self._make_type_annotation(False, result_bits))
コード例 #3
0
ファイル: ast_generator.py プロジェクト: mfkiwl/xls
    def _generate_array_concat(
            self, env: Env) -> Tuple[ast.Expr, ast.TypeAnnotation]:
        """Returns a binary concatenation of two arrays in env.

    The two arrays to concatenate in env will have the same element type.

    Args:
      env: Environment of values that can be selected from for array
        concatenation.
    Precondition: There must be an array value present in env.
    """
        make_lhs, lhs_type = self._choose_env_value(
            env, lambda t: isinstance(t, ast.ArrayTypeAnnotation))
        assert isinstance(lhs_type, ast.ArrayTypeAnnotation), lhs_type

        def array_same_elem_type(t: ast.TypeAnnotation) -> bool:
            return (isinstance(t, ast.ArrayTypeAnnotation)
                    and t.element_type == lhs_type.element_type)

        make_rhs, rhs_type = self._choose_env_value(env, array_same_elem_type)
        result = ast.Binop(self.m, self.fake_span, ast.BinopKind.CONCAT,
                           make_lhs(), make_rhs())
        lhs_size = self._get_array_size(lhs_type)
        bits_per_elem = self._get_type_bit_count(lhs_type) // lhs_size
        result_size = lhs_size + self._get_array_size(rhs_type)
        dim = self._make_number(result_size, None)
        result_type = ast.ArrayTypeAnnotation(self.m, self.fake_span,
                                              lhs_type.element_type, dim)
        self._type_bit_counts[str(result_type)] = bits_per_elem * result_size
        return (result, result_type)
コード例 #4
0
ファイル: ast_generator.py プロジェクト: masc-ucsc/xls
  def _generate_array_concat(self,
                             env: Env) -> Tuple[ast.Expr, ast.TypeAnnotation]:
    """Returns a binary concatenation of two arrays in env.

    The two arrays to concatenate in env will have the same element type.

    Args:
      env: Environment of values that can be selected from for array
        concatenation.
    Precondition: There must be an array value present in env.
    """
    make_lhs, lhs_type = self._choose_env_value(env, self._is_array)

    # Returns true if the type 't' is an array with the same element type as the
    # lhs and when concatentated, the type does not exceed bit count limits.
    def array_compatible(t: ast.TypeAnnotation) -> bool:
      return (isinstance(t, ast.ArrayTypeAnnotation) and
              t.element_type == lhs_type.element_type and
              (self._get_type_bit_count(lhs_type) +
               self._get_type_bit_count(t) <
               self.options.max_width_aggregate_types))

    make_rhs, rhs_type = self._choose_env_value(env, array_compatible)

    result = ast.Binop(self.m, self.fake_span, ast.BinopKind.CONCAT, make_lhs(),
                       make_rhs())
    result_size = (
        self._get_array_size(lhs_type) + self._get_array_size(rhs_type))
    dim = self._make_number(result_size, None)
    result_type = ast.ArrayTypeAnnotation(self.m, self.fake_span,
                                          lhs_type.element_type, dim)
    return (result, result_type)
コード例 #5
0
ファイル: ast_generator.py プロジェクト: masc-ucsc/xls
 def _generate_binop_same_input_type(
     self, lhs: ast.Expr, rhs: ast.Expr,
     input_type: ast.TypeAnnotation) -> Tuple[ast.Binop, ast.TypeAnnotation]:
   """Generates a binary operator on lhs/rhs which have the same input type."""
   if self.rng.random() < 0.1:
     op = self.rng.choice(ast_helpers.BINOP_COMPARISON_KIND_LIST)
     output_type = self._make_type_annotation(False, 1)
   else:
     op = self.rng.choice(self._binops)
     if op in ast_helpers.BINOP_SHIFTS and self.rng.random() < 0.8:
       # Clamp the RHS to be in range most of the time.
       assert self._is_bit_vector(input_type), input_type
       bit_count = self._get_type_bit_count(input_type)
       new_upper = self.rng.randrange(bit_count)
       rhs = self._generate_umin(rhs, input_type, new_upper)
     output_type = input_type
   return ast.Binop(self.m, self.fake_span, op, lhs, rhs), output_type
コード例 #6
0
ファイル: ast_generator.py プロジェクト: mfkiwl/xls
 def _make_ge(self, lhs: ast.Expr, rhs: ast.Expr) -> ast.Expr:
     return ast.Binop(self.m, self.fake_span, ast.BinopKind.GE, lhs, rhs)
コード例 #7
0
 def test_binop(self):
     m = cpp_ast.Module('test')
     ft = cpp_ast.Number(m, self.fake_span, '42')
     sf = cpp_ast.Number(m, self.fake_span, '64')
     add = cpp_ast.Binop(m, self.fake_span, cpp_ast.BinopKind.ADD, ft, sf)
     self.assertEqual(str(add), '(42) + (64)')
コード例 #8
0
ファイル: ast_test.py プロジェクト: mfkiwl/xls
 def test_format_binop(self):
     m = ast.Module('test')
     fake_pos = self.fake_pos
     fake_span = Span(fake_pos, fake_pos)
     le = ast.Binop(m, fake_span, ast.BinopKind.LE, self.five, self.five)
     self.assertEqual('(5) <= (5)', str(le))