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'))
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)