def generate_consumer(self, context: RuntimeGeneratorContext, connection: SignalConnection, consumer_instance_name, attributes): caller_fn = context.get_port(connection.provider).functions['run'] fn_to_call = context.get_port(consumer_instance_name).functions['run'] manual_args = {} consumer_instance = context.get_component_instance( consumer_instance_name) provider_instance = context.get_component_instance(connection.provider) callee_instance_arg_name = get_instance_argument( list(fn_to_call.arguments.keys()), consumer_instance) if callee_instance_arg_name: manual_args[ callee_instance_arg_name] = '&' + consumer_instance.instance_var_name caller_args = caller_fn.arguments.copy() passed_arguments = collect_arguments(attributes, consumer_instance_name, fn_to_call.arguments, caller_args, manual_args) provider_port_name = context.get_component_ref(connection.provider) body = fn_to_call.generate_call(passed_arguments) + ';' used_args = list(passed_arguments.keys()) instance_arg_name = get_instance_argument(list(caller_args.keys()), provider_instance) if instance_arg_name: used_args.append(instance_arg_name) body = add_instance_check(body, provider_instance, instance_arg_name=instance_arg_name) return { provider_port_name: { 'run': { 'body': body, 'used_arguments': used_args }, 'write': { 'body': body, 'used_arguments': used_args } } }
def generate_consumer(self, context: RuntimeGeneratorContext, connection: SignalConnection, consumer_instance_name, attributes): provider_port_data = context.get_port(connection.provider) consumer_port_data = context.get_port(consumer_instance_name) consumer_port_name = context.get_component_ref(consumer_instance_name) member_accessor, data_type = process_member_access( context.types, attributes, provider_port_data['data_type'], consumer_port_data['data_type']) function = context.functions[consumer_port_name]['read'] argument_names = list(function.arguments.keys()) consumer_instance = context.get_component_instance( consumer_instance_name) instance_argument = get_instance_argument(argument_names, consumer_instance) used_args = [] return_statement = None if 'count' not in consumer_port_data: # single read, index should be next to consumer name try: index = attributes['index'] except KeyError as e: raise Exception( f'{consumer_instance_name} tries to read from an ' f'array without specifying the element') from e else: if consumer_port_data['count'] > provider_port_data['count']: raise Exception( f'{consumer_instance_name} signal count ({consumer_port_data["count"]}) ' f'is incompatible with {connection.provider} ({provider_port_data["count"]})' ) index = argument_names.pop(0) used_args.append(index) if data_type.passed_by() == TypeCollection.PASS_BY_VALUE: read = f'return {connection.name}[{index}]{member_accessor};' if instance_argument is not None: return_statement = data_type.render_value(None) else: out_name = argument_names[0] used_args.append(out_name) read = f'*{out_name} = {connection.name}[{index}]{member_accessor};' if instance_argument is not None: used_args.append(instance_argument) read = add_instance_check(read, consumer_instance, instance_arg_name=instance_argument) mods = {'body': read, 'used_arguments': used_args} if return_statement: mods['return_statement'] = return_statement return {consumer_port_name: {'read': mods}}
def generate_provider(self, context: RuntimeGeneratorContext, connection: SignalConnection, provider_instance_name): provider_port_data = context.get_port(provider_instance_name) provider_port_name = context.get_component_ref(provider_instance_name) data_type = context.types.get(provider_port_data['data_type']) function = context.functions[provider_port_name]['write'] argument_names = list(function.arguments.keys()) provider_instance = context.get_component_instance( provider_instance_name) instance_argument = get_instance_argument(argument_names, provider_instance) index, value = argument_names used_args = [index, value] if data_type.passed_by() == TypeCollection.PASS_BY_VALUE: body = f'{connection.name}[{index}] = {value};' else: body = f'{connection.name}[{index}] = *{value};' if instance_argument is not None: used_args.append(instance_argument) body = add_instance_check(body, provider_instance) return { provider_port_name: { 'write': { 'used_arguments': used_args, 'body': body } } }
def generate_provider(self, context: RuntimeGeneratorContext, connection: SignalConnection, provider_instance_name): provider_port_data = context.get_port(provider_instance_name) provider_port_name = context.get_component_ref(provider_instance_name) data_type = context.types.get(provider_port_data['data_type']) if connection.attributes['queue_length'] == 1: template = \ "{{ signal_name }}_overflow = {{ signal_name }}_data_valid;\n" \ "{{ signal_name }} = {{ value }};\n" \ "{{ signal_name }}_data_valid = true;" else: template = \ "if ({{ signal_name }}_count < {{ queue_length }}u)\n" \ "{\n" \ " ++{{ signal_name }}_count;\n" \ "}\n" \ "else\n" \ "{\n" \ " {{ signal_name }}_overflow = true;\n" \ "}\n" \ "size_t {{ signal_name }}_idx = {{ signal_name }}_write_index;\n" \ "{{ signal_name }}_write_index = ({{ signal_name }}_write_index + 1u) % {{ queue_length }}u;\n" \ "{{ signal_name }}[{{ signal_name }}_idx] = {{ value }};" function = context.functions[provider_port_name]['write'] argument_names = list(function.arguments.keys()) provider_instance = context.get_component_instance( provider_instance_name) instance_arg_name = get_instance_argument(argument_names, provider_instance) passed_by_value = data_type.passed_by() == TypeCollection.PASS_BY_VALUE value_arg = argument_names[0] used_args = [value_arg] body = chevron.render( template, { 'queue_length': connection.attributes['queue_length'], 'signal_name': connection.name, 'value': value_arg if passed_by_value else '*' + value_arg }) if instance_arg_name: used_args.append(instance_arg_name) body = add_instance_check(body, provider_instance, instance_arg_name=instance_arg_name) return { provider_port_name: { 'write': { 'used_arguments': used_args, 'body': body } } }
def generate_consumer(self, context: RuntimeGeneratorContext, connection: SignalConnection, consumer_instance_name, attributes): provider_port_data = context.get_port(connection.provider) consumer_port_data = context.get_port(consumer_instance_name) consumer_port_name = context.get_component_ref(consumer_instance_name) member_accessor, data_type = process_member_access( context.types, attributes, provider_port_data['data_type'], consumer_port_data['data_type']) function = context.functions[consumer_port_name]['read'] argument_names = list(function.arguments.keys()) consumer_instance = context.get_component_instance( consumer_instance_name) instance_argument = get_instance_argument(argument_names, consumer_instance) used_args = [] return_statement = None if data_type.passed_by() == TypeCollection.PASS_BY_VALUE: read = f'return {connection.name}{member_accessor};' if instance_argument is not None: return_statement = data_type.render_value(None) else: out_name = argument_names[0] read = f'*{out_name} = {connection.name}{member_accessor};' used_args.append(out_name) if instance_argument is not None: used_args.append(instance_argument) read = add_instance_check(read, consumer_instance, instance_arg_name=instance_argument) mods = {'body': read, 'used_arguments': used_args} if return_statement: mods['return_statement'] = return_statement return {consumer_port_name: {'read': mods}}
def generate_consumer(self, context: RuntimeGeneratorContext, connection: SignalConnection, consumer_instance_name, attributes): consumer_port_data = context.get_port(consumer_instance_name) caller_fn = consumer_port_data.functions['run'] fn_to_call = context.get_port(connection.provider).functions['run'] manual_args = {} consumer_instance = context.get_component_instance( consumer_instance_name) provider_instance = context.get_component_instance(connection.provider) instance_arg_name = get_instance_argument( list(caller_fn.arguments.keys()), consumer_instance) provider_instance_arg_name = get_instance_argument( list(fn_to_call.arguments.keys()), provider_instance) if provider_instance_arg_name: manual_args[ provider_instance_arg_name] = '&' + provider_instance.instance_var_name passed_arguments = collect_arguments(attributes, consumer_instance_name, fn_to_call.arguments, caller_fn.arguments, manual_args) consumer_port_name = context.get_component_ref(consumer_instance_name) return_statement = None if caller_fn.return_type != 'void': if caller_fn.return_type != fn_to_call.return_type: raise Exception( f'Callee return type is incompatible ({consumer_port_data["return_type"]} ' f'instead of {caller_fn.return_type})') body = f"return {fn_to_call.generate_call(passed_arguments)};" if provider_instance_arg_name: return_statement = context.types.get( caller_fn.return_type).render_value(None) else: body = fn_to_call.generate_call(passed_arguments) + ';' if attributes['conditions']: used_args = [ *passed_arguments.keys(), *attributes['conditions'].keys() ] conditions = (f'{arg} == {value}' for arg, value in attributes['conditions'].items()) body = f'if ({" && ".join(conditions)})\n' \ f'{{\n' \ f'{indent(body)}\n' \ f'}}' else: used_args = passed_arguments.keys() if instance_arg_name: body = add_instance_check(body, consumer_instance, instance_arg_name=instance_arg_name) mod = {'body': body, 'used_arguments': used_args} if return_statement: mod['return_statement'] = return_statement return {consumer_port_name: {'run': mod}}
def generate_consumer(self, context: RuntimeGeneratorContext, connection: SignalConnection, consumer_instance_name, attributes): provider_port_data = context.get_port(connection.provider) consumer_port_data = context.get_port(consumer_instance_name) consumer_port_name = context.get_component_ref(consumer_instance_name) member_accessor, data_type = process_member_access( context.types, attributes, provider_port_data['data_type'], consumer_port_data['data_type']) consumer_instance = context.get_component_instance( consumer_instance_name) provider_instance = context.get_component_instance(connection.provider) function = context.functions[consumer_port_name]['read'] argument_names = list(function.arguments.keys()) constant_provider = provider_port_data.functions['constant'] provider_argument_names = list(constant_provider.arguments.keys()) call_args = {} instance_arg_name = get_instance_argument(argument_names, consumer_instance) provider_instance_arg_name = get_instance_argument( provider_argument_names, provider_instance) if instance_arg_name: call_args[ instance_arg_name] = '&' + consumer_instance.instance_var_name used_args = [] if 'count' not in consumer_port_data: # single read, index should be next to consumer name try: index = attributes['index'] except KeyError as e: raise Exception( f'{consumer_instance_name} tries to read from a constant ' f'array without specifying the element') from e else: if consumer_port_data['count'] > provider_port_data['count']: raise Exception( f'{consumer_instance_name} signal count ({consumer_port_data["count"]}) ' f'is incompatible with {connection.provider} ({provider_port_data["count"]})' ) index = argument_names.pop(0) used_args.append(index) call_args['index'] = index return_statement = None if data_type.passed_by() == TypeCollection.PASS_BY_VALUE: call = constant_provider.generate_call(call_args) body = f'return {call}{member_accessor};' if provider_instance_arg_name: return_statement = data_type.render_value(None) else: out_name = argument_names[0] used_args.append(out_name) if member_accessor: call_args['value'] = '&tmp' call = constant_provider.generate_call(call_args) body = f'{data_type.name} tmp;\n' \ f'{call};\n' \ f'{out_name} = tmp{member_accessor};' else: call_args['value'] = out_name body = constant_provider.generate_call(call_args) + ';' if provider_instance_arg_name: used_args.append(provider_instance_arg_name) body = add_instance_check( body, consumer_instance, instance_arg_name=provider_instance_arg_name) mods = {'body': body, 'used_arguments': used_args} if return_statement: mods['return_statement'] = return_statement return {consumer_port_name: {'read': mods}}
def generate_consumer(self, context: RuntimeGeneratorContext, connection: SignalConnection, consumer_instance_name, attributes): provider_port_data = context.get_port(connection.provider) consumer_port_data = context.get_port(consumer_instance_name) consumer_port_name = context.get_component_ref(consumer_instance_name) member_accessor, data_type = process_member_access( context.types, attributes, provider_port_data['data_type'], consumer_port_data['data_type']) consumer_instance = context.get_component_instance( consumer_instance_name) provider_instance = context.get_component_instance(connection.provider) function = context.functions[consumer_port_name]['read'] argument_names = list(function.arguments.keys()) constant_provider = provider_port_data.functions['constant'] provider_argument_names = list(constant_provider.arguments.keys()) call_args = {} instance_arg_name = get_instance_argument(argument_names, consumer_instance) provider_instance_arg_name = get_instance_argument( provider_argument_names, provider_instance) if instance_arg_name: call_args[ instance_arg_name] = '&' + consumer_instance.instance_var_name used_args = [] return_statement = None if data_type.passed_by() == TypeCollection.PASS_BY_VALUE: call = constant_provider.generate_call(call_args) body = f'return {call}{member_accessor};' if provider_instance_arg_name: return_statement = data_type.render_value(None) else: out_arg_name = argument_names[0] used_args.append(out_arg_name) if member_accessor: call_args['value'] = '&tmp' body = f"{data_type.name} tmp;\n" \ f"{constant_provider.generate_call(call_args)};\n" \ f"{out_arg_name} = tmp{member_accessor};" else: call_args['value'] = out_arg_name body = constant_provider.generate_call(call_args) + ';' if provider_instance_arg_name: used_args.append(provider_instance_arg_name) body = add_instance_check( body, consumer_instance, instance_arg_name=provider_instance_arg_name) mods = {'used_arguments': used_args, 'body': body} if return_statement: mods['return_statement'] = return_statement return {consumer_port_name: {'read': mods}}
def generate_consumer(self, context: RuntimeGeneratorContext, connection: SignalConnection, consumer_instance_name, attributes): provider_port_data = context.get_port(connection.provider) consumer_port_data = context.get_port(consumer_instance_name) consumer_port_name = context.get_component_ref(consumer_instance_name) member_accessor, data_type = process_member_access( context.types, attributes, provider_port_data['data_type'], consumer_port_data['data_type']) if connection.attributes['queue_length'] == 1: template = \ "bool was_overflow = {{ signal_name }}_overflow;\n" \ "if ({{ signal_name }}_data_valid)\n" \ "{\n" \ " {{ signal_name }}_overflow = false;\n" \ " {{ out_name }} = {{ signal_name }}{{ member_accessor }};\n" \ " {{ signal_name }}_data_valid = false;\n" \ " if (was_overflow)\n" \ " {\n" \ " return QueueStatus_Overflow;\n" \ " }\n" \ " else\n" \ " {\n" \ " return QueueStatus_Ok;\n" \ " }\n" \ "}" else: template = \ "if ({{ signal_name }}_count > 0u)\n" \ "{\n" \ " size_t idx = ({{ signal_name }}_write_index - {{ signal_name }}_count) % {{ queue_length }}u;\n" \ " --{{ signal_name }}_count;\n" \ " {{ out_name }} = {{ signal_name }}[idx]{{ member_accessor }};\n" \ " \n" \ " if ({{ signal_name }}_overflow)\n" \ " {\n" \ " {{ signal_name }}_overflow = false;\n" \ " return QueueStatus_Overflow;\n" \ " }\n" \ " else\n" \ " {\n" \ " return QueueStatus_Ok;\n" \ " }\n" \ "}" function = context.functions[consumer_port_name]['read'] argument_names = list(function.arguments.keys()) consumer_instance = context.get_component_instance( consumer_instance_name) instance_arg_name = get_instance_argument(argument_names, consumer_instance) value_arg = argument_names[0] data = { 'queue_length': connection.attributes['queue_length'], 'signal_name': connection.name, 'out_name': '*' + value_arg, 'member_accessor': member_accessor } read = chevron.render(template, data) used_args = [value_arg] if instance_arg_name: used_args.append(instance_arg_name) read = add_instance_check(read, consumer_instance, instance_arg_name=instance_arg_name) return { consumer_port_name: { 'read': { 'used_arguments': used_args, 'body': read, 'return_statement': 'QueueStatus_Empty' } } }