Esempio n. 1
0
    def generate_flow_network(self, fig_subgraph_view) -> MINTDevice:
        # TODO - For now just assume that the networks basically are a bunch
        # of nodes with nets/channels connecting them
        ret = MINTDevice("flow_network_temp")
        for node in fig_subgraph_view.nodes:
            n = MINTNode("node_{}".format(node))
            ret.add_component(n)
            self._store_fig_netlist_name(node, n.ID)

        i = 1
        for node in fig_subgraph_view.nodes:
            # Create the channel between these nodes
            channel_name = "c_{}".format(i)
            i += 1
            params = dict()
            params["channelWidth"] = 400
            source = MINTTarget("node_{}".format(node))
            sinks = []

            # Add all the outgoing edges
            for edge in fig_subgraph_view.out_edges(node):
                tar = edge[1]
                if tar not in fig_subgraph_view.nodes:
                    # We skip because this might be a weird edge that we were not supposed
                    # to have in this network
                    continue

                sinks.append(MINTTarget("node_{}".format(tar)))

            ret.addConnection(channel_name, "CHANNEL", params, source, sinks,
                              '0')

        return ret
Esempio n. 2
0
 def __init__(self):
     super().__init__()
     self.current_device: MINTDevice = MINTDevice("DEFAULT_NAME")
     self.current_block_id = 0
     self.current_layer_id = 0
     self.flow_layer_count = 0
     self.control_layer_count = 0
     self.integration_layer_count = 0
     self.current_entity: Optional[str] = None
     self.current_params: Dict = {}
     self._current_layer: Optional[Layer] = None
Esempio n. 3
0
 def enterNetlist(self, ctx: mintParser.NetlistContext):
     self.current_device = MINTDevice("DEFAULT_NAME")
Esempio n. 4
0
def generate(module: Module, library: MappingLibrary) -> MINTDevice:

    construction_graph = ConstructionGraph()

    name_generator = NameGenerator()

    cur_device = MINTDevice(module.name)

    # Add a MINT Layer so that the device has something to work with
    cur_device.create_mint_layer("0", "0", 0, MINTLayerType.FLOW)

    # TODO - I need to change this DummyStrategy later on
    if library.name == "dropx":
        active_strategy = DropXStrategy(construction_graph, module.FIG)
    elif library.name == "mars":
        raise NotImplementedError()
    elif library.name == "hmlp":
        raise NotImplementedError()
    else:
        active_strategy = DummyStrategy(construction_graph, module.FIG)

    # First go through all the interactions in the design

    # IF interaction is mix/sieve/divide/dilute/meter look at the library
    # to get all the options available and set them up as options for the
    # construction graph to pick and choose from the options.
    #
    # FUTURE WORK
    #
    # Do the regex matching to find the mapping options
    # This means that we might need to have a forest of construction of graphs
    # as there would be alternatives for each type of mapping
    for interaction in module.FIG.get_interactions():
        operator_candidates = library.get_operators(
            interaction_type=interaction.type)
        cn = ConstructionNode(interaction.id)
        # if isinstance(interaction, ValueNode):
        #     continue

        for operator_candidate in operator_candidates:
            # TODO: This will change in the future when we can match subgraphs correctly
            if isinstance(interaction,
                          (FluidNumberInteraction, FluidIntegerInteraction)):
                # Basically add the value node id into the subgraph view also
                node_ids = [
                    module.FIG.get_fignode(edge[0]).id
                    for edge in module.FIG.in_edges(interaction.id)
                    if isinstance(module.FIG.get_fignode(edge[0]), ValueNode)
                ]
                node_ids.append(interaction.id)
                sub_graph = module.FIG.subgraph(node_ids)
            else:
                sub_graph = module.FIG.subgraph(interaction.id)
            mapping_option = MappingOption(operator_candidate, sub_graph)
            cn.add_mapping_option(mapping_option)

        construction_graph.add_construction_node(cn)

    # Generate all ports necessary for the Explicitly declared IO
    # -------
    # Generate the flow layer IO. These are typically declared explicitly
    # TODO - Figure out how we should generate the construction nodes for control networks

    for io_ref in module.io:
        if io_ref.type is IOType.CONTROL:
            continue
        for io in io_ref.vector_ref:
            cn = ConstructionNode(io.id)
            sub_graph = module.FIG.subgraph(io.id)
            mapping_candidate = library.get_default_IO()
            mapping_option = MappingOption(mapping_candidate, sub_graph)
            cn.add_mapping_option(mapping_option)

            construction_graph.add_construction_node(cn)

    # Map the storage and pump elements to their own individual construction graph nodes
    for fig_node_id in list(module.FIG.nodes):
        fig_node = module.FIG.get_fignode(fig_node_id)
        if isinstance(fig_node, Pump):
            cn = ConstructionNode(fig_node.id)
            sub_graph = module.FIG.subgraph(fig_node_id)
            mapping_candidates = library.get_pump_entries()
            for mapping_candidate in mapping_candidates:
                mapping_option = MappingOption(mapping_candidate, sub_graph)
                cn.add_mapping_option(mapping_option)

        elif isinstance(fig_node, Storage):
            cn = ConstructionNode(fig_node.id)
            sub_graph = module.FIG.subgraph(fig_node_id)
            mapping_candidates = library.get_storage_entries()
            for mapping_candidate in mapping_candidates:
                mapping_option = MappingOption(mapping_candidate, sub_graph)
                cn.add_mapping_option(mapping_option)

    # TODO - Validate if this is a legit way to do things
    mappings = module.get_explicit_mappings()
    override_network_mappings(mappings, library, module.FIG,
                              construction_graph)

    # TODO - Go through the different flow-flow edge networks to generate construction nodes
    # specific to these networks, Conditions:
    # if its a 1-1 flow-flow connection, then create a construction node for the two flow nodes
    # if its a 1-n / n-1 / n-n construction nodes, then create a construction node capturing the whole network

    # TODO - Deal with coverage issues here since we need to figure out what are the flow networks,
    # that we want to match first and then ensure that they're no included on any list
    cn_nodes = get_flow_flow_candidates(module, active_strategy)
    for cn in cn_nodes:
        construction_graph.add_construction_node(cn)

    # Apply all the explicit mappings in the module to the nodes, overwriting
    # the options from the library to match against
    # TODO - Modify Explicit Mapping Data structure

    # Find all the explicit mappings and override them in the construction graph
    override_mappings(mappings, library, module.FIG, construction_graph)

    # Whittle Down the mapping options here to only include the requried single candidates
    # TODO - Check what library is being used and use the required library here
    active_strategy.reduce_mapping_options()

    # TODO - Consider what needs to get done for a combinatorial design space
    # ----------------
    # Generate edges in the construction graph, these edges will guide the generation/
    # reduction of path and pipelineing that needs to get done for mars devices
    construction_graph.generate_edges(module.FIG)

    # TODO - Extract all pass through networks
    eliminate_passthrough_nodes(construction_graph)

    # Now since all the mapping options are finalized Extract the netlist necessary
    construction_graph.construct_components(name_generator, cur_device)

    construction_graph.construct_connections(name_generator, cur_device)

    # Finally join all the netlist pieces attached to the construction nodes
    # and the input/output/load/carrier flows
    # TODO - MINIMIZE - carrier / load flows - this might require us to generate
    # multiple netlist options and pick the best
    construction_graph.generate_flow_cn_edges(module)

    construction_graph.generate_control_cn_edges(module)

    # Generate all the unaccounted carriers and waste output lines necessary
    # for this to function
    connect_orphan_IO()

    # Size the component netlist
    active_strategy.size_netlist(cur_device)

    return cur_device