def test_evaluate_ir_wide(self): sample_dir = self._make_sample_dir() runner = sample_runner.SampleRunner(sample_dir) dslx_text = 'fn main(x: bits[100], y: bits[100]) -> bits[100] { x + y }' runner.run( sample.Sample( dslx_text, sample.SampleOptions(optimize_ir=False), [[ Value.make_bits(Tag.UBITS, ir_bits.from_long(10**30, bit_count=100)), Value.make_bits(Tag.UBITS, ir_bits.from_long(10**30, bit_count=100)) ], [ Value.make_bits(Tag.UBITS, ir_bits.from_long(2**80, bit_count=100)), Value.make_bits(Tag.UBITS, ir_bits.from_long(2**81, bit_count=100)) ]])) self.assertSequenceEqual( _split_nonempty_lines(sample_dir, 'sample.x.results'), [ 'bits[100]:0x9_3e59_39a0_8ce9_dbd4_8000_0000', 'bits[100]:0x3_0000_0000_0000_0000_0000' ]) self.assertSequenceEqual( _split_nonempty_lines(sample_dir, 'sample.ir.results'), [ 'bits[100]:0x9_3e59_39a0_8ce9_dbd4_8000_0000', 'bits[100]:0x3_0000_0000_0000_0000_0000' ])
def _generate_bit_value(bit_count: int, rng: ast_generator.RngState, signed: bool) -> Value: assert isinstance(bit_count, int), bit_count assert isinstance(rng, ast_generator.RngState), rng bits = ast_generator.choose_bit_pattern(bit_count, rng) tag = Tag.SBITS if signed else Tag.UBITS return Value.make_bits(tag, bits)
def _generate_bit_value(bit_count: int, rng: Random, signed: bool) -> Value: assert isinstance(bit_count, int), bit_count p = rng.random() if p < 0.9: # Most of the time, use some interesting bit pattern. value = rng.choice(ast_generator.make_bit_patterns(bit_count)) else: # 10% of the time use a completely random value. value = rng.randrange(0, 2**bit_count) tag = Tag.SBITS if signed else Tag.UBITS return Value.make_bits(tag, ir_bits.from_long(value=value, bit_count=bit_count))
def ir_value_to_interpreter_value(value: ir_value_mod.Value) -> Value: """Converts an IR Value to an interpreter Value.""" if value.is_bits(): return Value.make_bits(Tag.UBITS, value.get_bits()) elif value.is_array(): return Value.make_array( tuple(ir_value_to_interpreter_value(e) for e in value.get_elements())) else: assert value.is_tuple() return Value.make_tuple( tuple(ir_value_to_interpreter_value(e) for e in value.get_elements()))
def _bit_value_from_scanner(s: Scanner, signed: bool) -> Value: s.pop_or_error(TokenKind.OBRACK) bit_count_tok = s.pop_or_error(TokenKind.NUMBER) s.pop_or_error(TokenKind.CBRACK) s.pop_or_error(TokenKind.COLON) value_tok = s.pop_or_error(TokenKind.NUMBER) tag = Tag.SBITS if signed else Tag.UBITS return Value.make_bits( tag, ir_bits.from_long( bit_count=ast_helpers.get_token_value_as_int(bit_count_tok), value=ast_helpers.get_token_value_as_int(value_tok)))
def generate_argument(arg_type: ConcreteType, rng: ast_generator.RngState, prior: Sequence[Value]) -> Value: """Generates an argument value of the same type as the concrete type.""" if isinstance(arg_type, TupleType): return Value.make_tuple( tuple( generate_argument(t, rng, prior) for t in arg_type.get_unnamed_members())) elif isinstance(arg_type, ArrayType): return Value.make_array( tuple( generate_argument(arg_type.get_element_type(), rng, prior) for _ in range(arg_type.size.value))) else: assert isinstance(arg_type, BitsType) if not prior or rng.random() < 0.5: return _generate_unbiased_argument(arg_type, rng) # Try to mutate a prior argument. If it happens to not be a bits type then # just generate an unbiased argument. index = rng.randrange(len(prior)) if not prior[index].is_bits(): return _generate_unbiased_argument(arg_type, rng) to_mutate = prior[index].get_bits() bit_count = arg_type.get_total_bit_count().value if bit_count > to_mutate.bit_count(): addendum = _generate_bit_value(bit_count - to_mutate.bit_count(), rng, signed=False) assert addendum.get_bit_count() + to_mutate.bit_count() == bit_count to_mutate = to_mutate.concat(addendum.get_bits()) else: to_mutate = to_mutate.slice(0, bit_count) assert to_mutate.bit_count() == bit_count, (to_mutate.bit_count(), bit_count) value = to_mutate.to_uint() mutation_count = rng.randrange_biased_towards_zero(bit_count) for _ in range(mutation_count): # Pick a random bit and flip it. bitno = rng.randrange(bit_count) value ^= 1 << bitno signed = arg_type.get_signedness() tag = Tag.SBITS if signed else Tag.UBITS return Value.make_bits(tag, ir_bits.from_long(value=value, bit_count=bit_count))
def ir_value_to_interpreter_value(value: ir_value_mod.Value) -> Value: """Converts an IR Value to an interpreter Value.""" if value.is_bits(): if value.get_bits().bit_count() <= 64: return Value.make_bits(Tag.UBITS, value.get_bits()) else: # For wide values which do not fit in 64 bits, parse value as as string. return value_from_string(value.to_str(FormatPreference.HEX)) elif value.is_array(): return Value.make_array( tuple(ir_value_to_interpreter_value(e) for e in value.get_elements())) else: assert value.is_tuple() return Value.make_tuple( tuple(ir_value_to_interpreter_value(e) for e in value.get_elements()))
def sign_convert_value(concrete_type: ConcreteType, value: Value) -> Value: """Converts the values to matched the signedness of the concrete type. Converts bits-typed Values contained within the given Value to match the signedness of the ConcreteType. Examples: invocation: sign_convert_value(s8, u8:64) returns: s8:64 invocation: sign_convert_value(s3, u8:7) returns: s3:-1 invocation: sign_convert_value((s8, u8), (u8:42, u8:10)) returns: (s8:42, u8:10) This conversion functionality is required because the Values used in the DSLX may be signed while Values in IR interpretation and Verilog simulation are always unsigned. This function is idempotent. Args: concrete_type: ConcreteType to match. value: Input value. Returns: Sign-converted value. """ if isinstance(concrete_type, concrete_type_mod.TupleType): assert value.is_tuple() assert len(value.get_elements()) == concrete_type.get_tuple_length() return Value.make_tuple( tuple( sign_convert_value(t, a) for t, a in zip( concrete_type.get_unnamed_members(), value.get_elements()))) elif isinstance(concrete_type, concrete_type_mod.ArrayType): assert value.is_array() assert len(value.get_elements()) == concrete_type.size return Value.make_array( tuple( sign_convert_value(concrete_type.get_element_type(), v) for v in value.get_elements())) elif concrete_type_mod.is_sbits(concrete_type): return Value.make_bits(Tag.SBITS, value.get_bits()) else: assert concrete_type_mod.is_ubits(concrete_type) return value