def test_8_bit_add_verilog(self):
     ir_text = opgen.generate_ir_package('add',
                                         output_type='bits[8]',
                                         operand_types=('bits[8]',
                                                        'bits[8]'))
     verilog_text = opgen.generate_verilog_module('add_module',
                                                  ir_text).verilog_text
     self.assertIn('module add_module', verilog_text)
     self.assertIn('p0_op0 + p0_op1', verilog_text)
    def test_parallel_add_verilog(self):
        add8_ir = opgen.generate_ir_package('add',
                                            output_type='bits[8]',
                                            operand_types=('bits[8]',
                                                           'bits[8]'))
        add16_ir = opgen.generate_ir_package('add',
                                             output_type='bits[16]',
                                             operand_types=('bits[16]',
                                                            'bits[16]'))
        add24_ir = opgen.generate_ir_package('add',
                                             output_type='bits[24]',
                                             operand_types=('bits[24]',
                                                            'bits[24]'))

        modules = (opgen.generate_verilog_module('add8_module', add8_ir),
                   opgen.generate_verilog_module('add16_module', add16_ir),
                   opgen.generate_verilog_module('add24_module', add24_ir))
        parallel_module = opgen.generate_parallel_module(modules, 'foo')
        self.assertEqual(
            parallel_module,
            runfiles.get_contents_as_text(
                'xls/delay_model/testdata/parallel_op_module.vtxt'))
Exemple #3
0
    def _generate_sources(
            self, op: op_pb2.OpProto,
            operand_types: Iterable[xls_type_pb2.TypeProto],
            output_type: xls_type_pb2.TypeProto) -> Tuple[str, str]:
        """Generates XLS IR and netlist sources for a single LEC execution.

    This function creates IR and a netlist for the given op and argument/output
    types, suitable as inputs to a LEC operation.

    Currently, this only supports a single op (per the internal operation of
    op_module_generator). In the future, it will likely be useful to see how
    execution time scales with operation composition.

    Args:
      op: The XLS IR opcode for which to generate sources.
      operand_types: The types of the arguments to use for this op execution.
      output_type: The type of the operation output.

    Returns:
      A tuple of IR and netlist sources for executing the given operation as
      text.
    """
        op_name = op_pb2.OpProto.Name(op)[3:].lower()
        operand_type_strs = [
            self._proto_to_ir_type(ot) for ot in operand_types
        ]
        ir_text = op_module_generator.generate_ir_package(
            op_name, self._proto_to_ir_type(output_type), operand_type_strs,
            [], None)
        verilog_text = op_module_generator.generate_verilog_module(
            self._MODULE_NAME, ir_text).verilog_text

        creds = client_credentials.get_credentials()
        netlist_text = None
        with grpc.secure_channel(self._synthesis_server_address,
                                 creds) as channel:
            grpc.channel_ready_future(channel).result()
            stub = synthesis_service_pb2_grpc.SynthesisServiceStub(channel)

            request = synthesis_pb2.CompileRequest()
            logging.vlog(logging.INFO, 'Module text:\n %s', verilog_text)
            request.module_text = verilog_text
            request.top_module_name = self._MODULE_NAME
            # We're always going to be in a single cycle.
            request.target_frequency_hz = 1

            response = stub.Compile(request)
            netlist_text = response.netlist

        return (ir_text, netlist_text)
def _synthesize_op_and_make_bare_data_point(
        op: str,
        kop: str,
        op_type: str,
        operand_types: List[str],
        stub: synthesis_service_pb2_grpc.SynthesisServiceStub,
        attributes: Sequence[Tuple[str, str]] = (),
        literal_operand: Optional[int] = None) -> delay_model_pb2.DataPoint:
    """Characterize an operation via synthesis server.

  Sets the area and op of the data point but not any other information about the
  node / operands.

  Args:
    op: Operation name to use for generating an IR package; e.g. 'add'.
    kop: Operation name to emit into datapoints, generally in kConstant form for
      use in the delay model; e.g. 'kAdd'.
    op_type: The type of the operation result.
    operand_types: The type of each operation.
    stub: Handle to the synthesis server.
    attributes: Attributes to include in the operation mnemonic. For example,
      "new_bit_count" in extend operations. Forwarded to generate_ir_package.
    literal_operand: Optionally specifies that the given operand number should
      be substituted with a randomly generated literal instead of a function
      parameter. Forwarded to generate_ir_package.

  Returns:
    datapoint produced via the synthesis server with the area and op (but no
    other fields)
    set.

  """
    ir_text = op_module_generator.generate_ir_package(op, op_type,
                                                      operand_types,
                                                      attributes,
                                                      literal_operand)
    module_name_safe_op_type = op_type.replace('[', '_').replace(']', '')
    module_name = f'{op}_{module_name_safe_op_type}'
    mod_generator_result = op_module_generator.generate_verilog_module(
        module_name, ir_text)
    top_name = module_name + '_wrapper'
    verilog_text = op_module_generator.generate_parallel_module(
        [mod_generator_result], top_name)

    response = _synth(stub, verilog_text, top_name)
    result = delay_model_pb2.DataPoint()
    _record_area(response, result)
    result.operation.op = kop

    return result
def _synthesize_ir(
        stub: synthesis_service_pb2_grpc.SynthesisServiceStub,
        ir_text: str,
        op: str,
        result_bit_count: int,
        operand_bit_counts=Sequence[int]) -> delay_model_pb2.DataPoint:
    """Synthesis the given IR text and return a data point."""
    module_name = 'top'
    mod_generator_result = op_module_generator.generate_verilog_module(
        module_name, ir_text)
    verilog_text = mod_generator_result.verilog_text
    result = _synth(stub, verilog_text, module_name)
    ps = 1e12 / result.max_frequency_hz
    result = delay_model_pb2.DataPoint()
    result.operation.op = op
    result.operation.bit_count = result_bit_count
    for bit_count in operand_bit_counts:
        operand = result.operation.operands.add()
        operand.bit_count = bit_count
    result.delay = int(ps)
    return result
def _synthesize_ir(stub: synthesis_service_pb2_grpc.SynthesisServiceStub,
                   model: delay_model_pb2.DelayModel,
                   data_points: Dict[str, Set[str]], ir_text: str, op: str,
                   result_bit_count: int,
                   operand_bit_counts: Sequence[int]) -> None:
    """Synthesizes the given IR text and returns a data point."""
    if op not in data_points:
        data_points[op] = set()

    bit_count_strs = []
    for bit_count in operand_bit_counts:
        operand = delay_model_pb2.Operation.Operand(bit_count=bit_count,
                                                    element_count=0)
        bit_count_strs.append(str(operand))
    key = ', '.join([str(result_bit_count)] + bit_count_strs)
    if key in data_points[op]:
        return
    data_points[op].add(key)

    logging.info('Running %s with %d / %s', op, result_bit_count,
                 ', '.join([str(x) for x in operand_bit_counts]))
    module_name = 'top'
    mod_generator_result = op_module_generator.generate_verilog_module(
        module_name, ir_text)
    verilog_text = mod_generator_result.verilog_text
    result = _synth(stub, verilog_text, module_name)
    logging.info('Result: %s', result)
    ps = 1e12 / result.max_frequency_hz
    result = delay_model_pb2.DataPoint()
    result.operation.op = op
    result.operation.bit_count = result_bit_count
    for bit_count in operand_bit_counts:
        operand = result.operation.operands.add()
        operand.bit_count = bit_count
    result.delay = int(ps)

    # Checkpoint after every run.
    model.data_points.append(result)
    save_checkpoint(model, FLAGS.checkpoint_path)