Esempio n. 1
0
    def __create_intercn_channel(self, src_id: str,
                                 name_generator: NameGenerator,
                                 cn: ConstructionNode,
                                 device: MINTDevice) -> None:
        src = self._construction_nodes[src_id]
        start_point = src.output_options[0]

        if start_point.component_name is None:
            # This means a single component was mapped here
            src_component_name = self._component_refs[src_id][0]
        else:
            src_component_name = name_generator.get_cn_name(
                src_id, start_point.component_name)

        end_point = cn.input_options[0]

        if end_point.component_name is None:
            # This means a single component was mapped here
            tar_component_name = self._component_refs[cn.id][0]
        else:
            tar_component_name = name_generator.get_cn_name(
                cn.id, end_point.component_name)

        print(
            "Generating the channel - Source: {0} {2}, Target: {1} {3}".format(
                src_component_name, tar_component_name,
                start_point.component_port, end_point.component_port))

        # TODO - Change how we retrieve the technology type for the channel
        tech_string = "CHANNEL"
        # channel_name = name_generator.generate_name(tech_string)

        # TODO - Figure out how to hande a scenario where this isn't ture
        assert (len(end_point.component_port) == 1)
        if len(start_point.component_port) == 0:
            channel_name = name_generator.generate_name(tech_string)
            source = MINTTarget(src_component_name, None)
            sink = MINTTarget(tar_component_name, end_point.component_port[0])
            device.addConnection(channel_name, tech_string, dict(), source,
                                 [sink], "0")
        else:
            for component_port in start_point.component_port:
                channel_name = name_generator.generate_name(tech_string)
                source = MINTTarget(src_component_name, component_port)
                sink = MINTTarget(tar_component_name,
                                  end_point.component_port[0])
                # TODO - Figure out how to make this layer generate automatically
                device.addConnection(channel_name, tech_string, dict(), source,
                                     [sink], "0")

        # TODO - Once we are done creating a path, we need to delete the start and end point options
        # from their respective construction nodes.
        print("Updated the connectionoptions in {} - Removing {}".format(
            src, start_point))
        src.output_options.remove(start_point)

        print("Updated the connectionoptions in {} - Removing {}".format(
            cn, end_point))
        cn.input_options.remove(end_point)
Esempio n. 2
0
    def generate_constraints(mirror_driving_components: List[Component],
                             mint_device: MINTDevice) -> None:
        """Generate the mirror constraints for the device

        Args:
            mirror_driving_components (List[Component]): components that are driving the mirror constraint
            device (MINTDevice): device to generate the constraint for
        """
        for mirror_driving_component in mirror_driving_components:
            in_mirror_count = mirror_driving_component.params.get_param("in")
            out_mirror_count = mirror_driving_component.params.get_param("out")

            if in_mirror_count > 1:
                # Find groups for in_mirror_count
                mirror_groups = MirrorConstraint.find_mirror_groups(
                    mirror_driving_component, mint_device.device,
                    in_mirror_count)

                print("In Mirror Groups")
                print(mirror_groups)

                if len(mirror_groups) > 0:
                    # If the number of mirror groups found is great than 0 generate the
                    # mirror constraint
                    mirror_constraint = MirrorConstraint(
                        source_component=mirror_driving_component,
                        mirror_count=len(mirror_groups),
                        mirror_groups=mirror_groups,
                    )

                    mint_device.add_constraint(mirror_constraint)

            if out_mirror_count > 1:
                # Find groups for out_mirror_count
                mirror_groups = MirrorConstraint.find_mirror_groups(
                    mirror_driving_component, mint_device.device,
                    out_mirror_count)
                print("Out Mirror Groups")
                print(mirror_groups)

                if len(mirror_groups) > 0:
                    # If the number of mirror groups found is great than 0 generate the
                    # mirror constraint
                    mirror_constraint = MirrorConstraint(
                        source_component=mirror_driving_component,
                        mirror_count=len(mirror_groups),
                        mirror_groups=mirror_groups,
                    )

                    mint_device.add_constraint(mirror_constraint)
Esempio n. 3
0
def assign_single_port_terminals(device: MINTDevice):
    #Loop through each of the connections
    for connection in device.connections:
        #Check if the source component has a single port
        source_component = device.getComponent(connection.source.component)

        if None == connection.source.port and len(source_component.ports) == 1:
            connection.source.port = source_component.ports[0].label

        for sink_target in connection.sinks:
            sink_component = device.getComponent(sink_target.component)

            if None == sink_target.port and len(sink_component.ports) == 1:
                sink_component.port = sink_component.ports[0].label
Esempio n. 4
0
def convert_to_parchmint(
    input_file: Path,
    outpath: Path,
    skip_constraints: bool = True,
    generate_graph_view: bool = False,
):
    """
    Convert a .mint file to a .parchmint.json file
    """
    extension = input_file.suffix
    if extension == ".mint" or extension == ".uf":
        current_device = MINTDevice.from_mint_file(str(input_file),
                                                   skip_constraints)

        # Save the device parchmint v1_2 to a file
        parchmint_text = current_device.to_parchmint()

        # Create new file in outpath with the same name as the current device
        outpath.mkdir(parents=True, exist_ok=True)
        with open(str(outpath.joinpath(input_file.stem + ".json")), "w") as f:
            print("Writing to file: {}".format(f.name))

            json.dump(parchmint_text, f, indent=4)

        # Generate a graph view of the device
        if generate_graph_view:
            printgraph(current_device.device.graph, current_device.device.name)
    else:
        raise Exception("Unsupported file extension: {}".format(extension))
Esempio n. 5
0
def serialize_netlist(device: MINTDevice) -> None:
    # Generate the MINT file from the pyparchmint device
    json_data = device.to_parchmint_v1()
    json_string = json.dumps(json_data)
    json_file = open(get_ouput_path(device.name + ".json"), "wt")
    json_file.write(json_string)
    json_file.close()
Esempio n. 6
0
    def get_default_netlist(self, cn_id: str,
                            name_gen: NameGenerator) -> MINTDevice:
        """Returns the default netlist for the primitive

        Args:
            cn_id (str): ID of the construction node so that we can prefix the id's of all the components that are part of the default netlist
            name_gen (NameGenerator): A namegenerator instance that is used for the globally for synthesizing the design

        Returns:
            MINTDevice: Default netlist of whatever the primitive is
        """
        if self.type is not PrimitiveType.NETLIST:
            raise Exception(
                "Cannot execute this method for this kind of a  primitive")

        default_mint_file = parameters.LIB_DIR.joinpath(
            self._default_netlist).resolve()

        device = MINTDevice.from_mint_file(str(default_mint_file))

        if device is None:
            raise Exception(
                "Unable to parse MINT file: {} for construction node {}".
                format(str(default_mint_file), cn_id))
        name_gen.rename_netlist(cn_id, device)
        # Return the default netlist
        return device
Esempio n. 7
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")
        mint_layer = ret.create_mint_layer("0", "0", 0, MINTLayerType.FLOW)
        for node in fig_subgraph_view.nodes:
            n = MINTNode("node_{}".format(node), mint_layer)
            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.create_mint_connection(channel_name, "CHANNEL", params, source,
                                       sinks, "0")

        return ret
Esempio n. 8
0
def test_mirror_test4():
    mint_file = "tests/mint_files/mirror_test4.mint"
    mint_device = MINTDevice.from_mint_file(mint_file)
    # Convert it to Parchmint
    parchmint_device = mint_device.to_parchmint()
    # Write the Parchmint to a file
    with open(mint_file.replace(".mint", ".json"), "r") as data_file:
        text = data_file.read()
        device_json = json.loads(text)
        assert ordered(parchmint_device) == ordered(device_json)
Esempio n. 9
0
def test_node_test2():
    mint_file = "tests/mint_files/node_test2.mint"
    mint_device = MINTDevice.from_mint_file(mint_file)
    # Convert it to Parchmint
    parchmint_device = mint_device.to_parchmint()
    # Write the Parchmint to a file
    with open(mint_file.replace(".mint", ".json"), "r") as data_file:
        text = data_file.read()
        device_json = json.loads(text)
        assert parchmint_device == device_json
Esempio n. 10
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. 11
0
    def construct_components(self, name_generator: NameGenerator,
                             device: MINTDevice) -> None:
        for cn in self.construction_nodes:
            if len(cn.mapping_options) > 1:
                # TODO - update for combinatorial design space exploration
                raise Exception(
                    "Does not support Combinatorial design exploration")
            elif len(cn.mapping_options) == 1:
                mapping_option = cn.mapping_options[0]

                # TODO - Make sure we skip the mapping option if pass through is enabled
                if isinstance(mapping_option, NetworkMappingOption):
                    if mapping_option.mapping_type is NetworkMappingOptionType.PASS_THROUGH:
                        continue

                if mapping_option.primitive.type is PrimitiveType.COMPONENT:
                    # Create a new component here based on the primitive technology
                    # and the name generator
                    # Then merge with the larger device
                    # Save the copy of subgraph view of the netlist in the construction node
                    component_to_add = mapping_option.primitive.get_default_component(
                        name_generator)
                    device.add_component(component_to_add)
                    self._component_refs[cn.id] = [component_to_add.ID]
                    # for connecting_option in cn
                    # TODO - save the subgraph view reference
                elif mapping_option.primitive.type is PrimitiveType.NETLIST:
                    netlist = mapping_option.primitive.get_default_netlist(
                        cn.id, name_generator)
                    self._component_refs[cn.id] = [
                        component.ID for component in netlist.components
                    ]
                    device.merge_netlist(netlist)
                    # TODO - Save the subgraph view reference
                elif mapping_option.primitive.type is PrimitiveType.PROCEDURAL:
                    netlist = mapping_option.primitive.get_default_netlist(
                        cn.id, name_generator)
                    self._component_refs[cn.id] = [
                        component.ID for component in netlist.components
                    ]
                    device.merge_netlist(netlist)
                else:
                    raise Exception(
                        "Does not work with any known option for primitive type"
                    )

                cn.load_connection_options()

            else:
                print("No mappings found to the current construction node {0}".
                      format(cn))
Esempio n. 12
0
class MINTCompiler(mintListener):
    """Primary ANTLR listener class for the compiler"""

    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

    def enterNetlist(self, ctx: mintParser.NetlistContext):
        self.current_device = MINTDevice("DEFAULT_NAME")

    def exitNetlist(self, ctx: mintParser.NetlistContext):
        if self.current_device is None:
            raise Exception("Could not find the device")

    def enterHeader(self, ctx: mintParser.HeaderContext):
        if self.current_device is None:
            raise Exception(
                "Error Initializing the device. Could not find the current device"
            )

        if ctx.device_name is None:
            raise Exception("Could not find Device Name")
        self.current_device.device.name = ctx.device_name.text

    def exitLayerBlock(self, ctx: mintParser.LayerBlockContext):
        # Increement teh layer block
        self.current_block_id += 1

    def enterFlowBlock(self, ctx: mintParser.FlowBlockContext):
        if self.current_device is None:
            raise Exception(
                "Error Initializing the device. Could not find the current device"
            )
        layer = self.current_device.create_mint_layer(
            str(self.current_layer_id),
            str(self.flow_layer_count),
            str(self.current_block_id),
            MINTLayerType.FLOW,
        )
        self._current_layer = layer
        self.flow_layer_count += 1
        self.current_layer_id += 1

    def enterControlBlock(self, ctx: mintParser.ControlBlockContext):
        if self.current_device is None:
            raise Exception(
                "Error Initializing the device. Could not find the current device"
            )

        layer = self.current_device.create_mint_layer(
            str(self.current_layer_id),
            str(self.control_layer_count),
            str(self.current_block_id),
            MINTLayerType.CONTROL,
        )
        self._current_layer = layer
        self.control_layer_count += 1
        self.current_layer_id += 1

    def enterIntegrationBlock(self, ctx: mintParser.IntegrationBlockContext):
        if self.current_device is None:
            raise Exception(
                "Error Initializing the device. Could not find the current device"
            )

        layer = self.current_device.create_mint_layer(
            str(self.current_layer_id),
            str(self.integration_layer_count),
            str(self.current_block_id),
            MINTLayerType.INTEGRATION,
        )
        self._current_layer = layer
        self.integration_layer_count += 1
        self.current_layer_id += 1

    def enterEntity(self, ctx: mintParser.EntityContext):
        self.current_entity = ctx.getText()

    def enterParamsStat(self, ctx: mintParser.ParamsStatContext):
        self.current_params = {}

    def enterIntParam(self, ctx: mintParser.IntParamContext):
        value = ctx.value().getText()  # type: ignore
        key = ctx.param_element().getText()  # type: ignore
        self.current_params[key] = int(value)

    def enterBoolParam(self, ctx: mintParser.BoolParamContext):
        if ctx.boolvalue.getText() == "YES":
            value = True
        else:
            value = False
        key = ctx.param_element.getText()
        self.current_params[key] = value

    def enterLengthParam(self, ctx: mintParser.LengthParamContext):
        value = float(ctx.value().getText())  # type: ignore
        self.current_params["length"] = value

    def enterSpacingParam(self, ctx: mintParser.SpacingParamContext):
        value = float(ctx.value().getText())  # type: ignore
        self.current_params["spacing"] = value

    def enterWidthParam(self, ctx: mintParser.WidthParamContext):
        value = ctx.value().getText()  # type: ignore
        if ctx.key is None:
            raise AssertionError
        key = ctx.key.text
        if key is None:
            raise Exception("Error in parsing the width parameter")
        if key == "w":
            key = "width"

        self.current_params[key] = int(value)

    def enterFlowStat(self, ctx: mintParser.FlowStatContext):
        self.current_entity = None
        self.current_params = {}

    def enterControlStat(self, ctx: mintParser.ControlStatContext):
        self.current_entity = None
        self.current_params = {}

    def exitPrimitiveStat(self, ctx: mintParser.PrimitiveStatContext):
        if self.current_device is None:
            raise Exception(
                "Error Initializing the device. Could not find the current device"
            )

        entity = self.current_entity
        if entity is None:
            raise Exception("Could not find the technology for the pimitive")

        # Loop for each of the components that need to be created with this param
        for ufname in ctx.ufnames().ufname():  # type: ignore
            if self._current_layer is None:
                raise Exception("Current layer is set to None")
            if not (
                self._current_layer is not None and self._current_layer.ID is not None
            ):
                raise AssertionError
            self.current_device.create_mint_component(
                ufname.getText(),
                entity,
                self.current_params,
                [self._current_layer.ID],
            )

    def exitBankDeclStat(self, ctx: mintParser.BankDeclStatContext):
        entity = self.current_entity
        if entity is None:
            raise Exception("Could not find the technology for the primitive")

        # Clean up the constraint specific params
        self._cleanup_bank_params()

        for ufname in ctx.ufnames().ufname():  # type: ignore
            component_name = ufname.getText()
            if self._current_layer is None:
                raise AssertionError
            self.current_device.create_mint_component(
                component_name,
                entity,
                self.current_params,
                [self._current_layer.ID],
            )

    def exitBankGenStat(self, ctx: mintParser.BankGenStatContext):
        entity = self.current_entity
        if entity is None:
            raise Exception("Could not find the technology for the primitive")

        self._cleanup_bank_params()

        if ctx.dim is None:
            raise AssertionError
        dim = int(ctx.dim.text)

        name = ctx.ufname().getText()  # type: ignore

        for i in range(1, dim + 1):
            component_name = name + "_" + str(i)
            if self._current_layer is None:
                raise Exception("Current Layer not Set")
            if not (
                self._current_layer is not None and self._current_layer.ID is not None
            ):
                raise AssertionError
            self.current_device.create_mint_component(
                component_name, entity, self.current_params, [self._current_layer.ID]
            )

    def exitGridDeclStat(self, ctx: mintParser.GridDeclStatContext):
        if self.current_device is None:
            raise Exception(
                "Error Initializing the device. Could not find the current device"
            )

        entity = self.current_entity
        if entity is None:
            raise Exception("Could not find the technology for the primitive")

        self._cleanup_grid_params()

        for ufname in ctx.ufnames().ufname():  # type: ignore
            component_name = ufname.getText()
            if self._current_layer is None:
                raise AssertionError
            self.current_device.create_mint_component(
                component_name,
                entity,
                self.current_params,
                [self._current_layer.ID],
            )

    def exitChannelStat(self, ctx: mintParser.ChannelStatContext):
        if self.current_device is None:
            raise Exception(
                "Error Initializing the device. Could not find the current device"
            )

        entity = self.current_entity
        if entity is None:
            entity = "CHANNEL"
        connection_name = ctx.ufname().getText()  # type: ignore

        source_target = ctx.uftarget()[0]  # type: ignore
        source_id = source_target.ID().getText()
        if self.current_device.device.component_exists(source_id) is False:
            raise Exception(
                "Error ! - Could not find the component '{}' in device '{}'".format(
                    source_id, self.current_device.device.name
                )
            )
        if source_target.INT():
            source_port = source_target.INT().getText()
        else:
            source_port = None

        # source_uftarget = Target(component_id=source_id, port=source_port)
        source_uftarget = Target(component_id=source_id, port=source_port)

        sink_target = ctx.uftarget()[1]  # type: ignore
        sink_id = sink_target.ID().getText()
        if self.current_device.device.component_exists(sink_id) is False:
            raise Exception(
                "Error ! - Could not find the component '{}' in device '{}'".format(
                    sink_id, self.current_device.device.name
                )
            )
        if sink_target.INT():
            sink_port = sink_target.INT().getText()
        else:
            sink_port = None

        sink_uftarget = Target(component_id=sink_id, port=sink_port)

        self._cleanup_channel_params()

        # Create a connection between the different components in the device
        if not (self._current_layer is not None and self._current_layer.ID is not None):
            raise AssertionError
        self.current_device.create_mint_connection(
            connection_name,
            entity,
            self.current_params,
            source_uftarget,
            [sink_uftarget],
            self._current_layer.ID,
        )

    def exitNetStat(self, ctx: mintParser.NetStatContext):
        entity = self.current_entity
        if entity is None:
            entity = "NET"

        connection_name = ctx.ufname().getText()  # type: ignore

        source_target = ctx.uftarget()
        source_id = source_target.ID().getText()  # type: ignore
        if source_target.INT():  # type: ignore
            source_port = source_target.INT().getText()  # type: ignore
        else:
            source_port = None

        source_uftarget = Target(component_id=source_id, port=source_port)

        sink_uftargets = []

        for sink_target in ctx.uftargets().uftarget():  # type: ignore
            sink_id = sink_target.ID().getText()
            if sink_target.INT():
                sink_port = sink_target.INT().getText()
            else:
                sink_port = None

            sink_uftargets.append(Target(component_id=sink_id, port=sink_port))
        if not (self._current_layer is not None and self._current_layer.ID is not None):
            raise AssertionError
        self.current_device.create_mint_connection(
            connection_name,
            entity,
            self.current_params,
            source_uftarget,
            sink_uftargets,
            self._current_layer.ID,
        )

    def exitSpanStat(self, ctx: mintParser.SpanStatContext):
        if self.current_device is None:
            raise Exception(
                "Error Initializing the device. Could not find the current device"
            )

        entity = self.current_entity
        if entity is None:
            raise Exception("Could not find the technology for the pimitive")

        # pipe in the in / out values to params for sizing
        if ctx.indim is not None:
            in_value = int(ctx.indim.text)
            self.current_params["in"] = in_value
        if ctx.outdim is not None:
            out_value = int(ctx.outdim.text)
            self.current_params["out"] = out_value

        # Loop for each of the components that need to be created with this param
        for ufname in ctx.ufnames().ufname():  # type: ignore
            if self._current_layer is None:
                raise AssertionError
            self.current_device.create_mint_component(
                ufname.getText(),
                entity,
                self.current_params,
                [self._current_layer.ID],
            )

    def exitNodeStat(self, ctx: mintParser.NodeStatContext):
        entity = "NODE"
        if self.current_device is None:
            raise Exception(
                "Error Initializing the device. Could not find the current device"
            )

        # Loop for each of the components that need to be created with this param
        if not (self._current_layer is not None and self._current_layer.ID is not None):
            raise AssertionError
        for ufname in ctx.ufnames().ufname():  # type: ignore
            self.current_device.create_mint_component(
                ufname.getText(),
                entity,
                self.current_params,
                [self._current_layer.ID],
            )

    def exitValveStat(self, ctx: mintParser.ValveStatContext):
        if self.current_device is None:
            raise Exception(
                "Error Initializing the device. Could not find the current device"
            )

        entity = self.current_entity
        if entity is None:
            logging.error("Could not find entitry information for valve")
            raise Exception("Could not find entitry information for valve")
        valve_name = ctx.ufname()[0].getText()  # type: ignore
        if not (self._current_layer is not None and self._current_layer.ID is not None):
            raise AssertionError
        valve_component = self.current_device.create_mint_component(
            valve_name,
            entity,
            self.current_params,
            [self._current_layer.ID],
        )
        connection_name = ctx.ufname()[1].getText()  # type: ignore
        valve_connection = self.current_device.device.get_connection(connection_name)
        if valve_connection is None:
            raise Exception(
                "Error: Could not find connection '{}' in device '{}'".format(
                    connection_name, self.current_device.device.name
                )
            )

        self.current_device.device.map_valve(valve_component, valve_connection)

    def enterViaStat(self, ctx: mintParser.ViaStatContext):
        if self.current_device is None:
            raise Exception(
                "Error Initializing the device. Could not find the current device"
            )

        for ufname in ctx.ufnames().ufname():
            self.current_device.add_via(ufname.getText(), [])

    def enterTerminalStat(self, ctx: mintParser.TerminalStatContext):
        if self.current_device is None:
            raise Exception(
                "Error Initializing the device. Could not find the current device"
            )

        terminal_name = ctx.ufname().getText()
        pin_number = int(ctx.INT.getText())
        if not (self._current_layer is not None and self._current_layer.ID is not None):
            raise AssertionError
        self.current_device.add_terminal(
            terminal_name,
            pin_number,
            self._current_layer.ID,
        )

    def _cleanup_bank_params(self):
        if "spacing" in self.current_params:
            del self.current_params["spacing"]

    def _cleanup_grid_params(self):
        if "horizontalSpacing" in self.current_params:
            del self.current_params["horizontalSpacing"]
        if "verticalSpacing" in self.current_params:
            del self.current_params["verticalSpacing"]

    def _cleanup_channel_params(self):
        if "length" in self.current_params:
            del self.current_params["length"]
Esempio n. 13
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
Esempio n. 14
0
def main():

    # parameters.PROGRAM_DIR = os.path.abspath(os.path.dirname(__file__))

    parser = argparse.ArgumentParser()

    parser.add_argument('input',
                        help="This is the file thats used as the input ")
    parser.add_argument('--outpath',
                        type=str,
                        default="out/",
                        help="This is the output directory")
    parser.add_argument(
        '-c',
        '--convert',
        action='store_true',
        help='Sets the flag to only convert the design and nothing else')

    args = parser.parse_args()

    ascii_banner = pyfiglet.figlet_format("Fluigi")
    print(ascii_banner)

    print("output dir:", args.outpath)
    print("Running File: " + args.input)

    extension = Path(args.input).suffix
    if extension != '.mint' and extension != '.uf':
        print("Unrecognized file Extension")
        exit()

    abspath = Path(args.outpath).resolve()
    parameters.OUTPUT_DIR = abspath

    if os.path.isdir(abspath) is not True:
        print("Creating the output directory:")
        path = Path(parameters.OUTPUT_DIR)
        path.mkdir(parents=True)

    #Check if the device netlist is planar
    current_device = MINTDevice.from_mint_file(args.input)
    graph = current_device.G

    if nx.algorithms.check_planarity(graph) == False:
        print('Error - Non-planar graph seen')
        sys.exit(0)

    try:
        pull_defaults(current_device)
        pull_dimensions(current_device)
    except Exception as e:
        print('Error getting Primitive data: {}'.format(e))

    layout = Layout()
    layout.importMINTwithoutConstraints(current_device)

    pull_defaults(current_device)
    pull_dimensions(current_device)
    pull_terminals(current_device)
    generateSpringLayout(layout)

    layout.applyLayout()

    tt = os.path.join(parameters.OUTPUT_DIR,
                      '{}_no_par.json'.format(current_device.name))
    with open(tt, 'w') as f:
        json.dump(current_device.to_parchmint_v1(), f)

    print(current_device.G.edges)

    utils.printgraph(current_device.G, current_device.name + '.dot')

    # We exit the process if only convert is set to true
    if args.convert:
        sys.exit(0)

    layout = Layout()
    layout.importMINTwithoutConstraints(current_device)

    #Do Terminal Assignment
    assign_single_port_terminals(current_device)

    # #Generate the Simulated Annealing Layout
    # generate_simulated_annealing_layout_v2(current_device)
    # generate_simulated_annealing_layout(layout)

    # generateSpectralLayout(layout)
    generateHOLALayout(layout)
    layout.applyLayout()
    layout.ensureLegalCoordinates()
    layout.print_layout()

    tt = os.path.join(parameters.OUTPUT_DIR,
                      '{}_hola_par.json'.format(current_device.name))
    with open(tt, 'w') as f:
        json.dump(current_device.to_parchmint_v1(), f)

    utils.printgraph(layout.G, current_device.name + '.layout.dot')
Esempio n. 15
0
def generate_simulated_annealing_layout_v2(device: MINTDevice) -> Layout:
    jsonstring = json.dumps(device.to_parchmint_v1())
    print(jsonstring)
    device = Fluigi.placeAndRouteDevice(jsonstring)

    print("PNR Executed"+ device.getName())
Esempio n. 16
0
    def __create_passthrough_channel(
        self,
        cn_start_id: str,
        cn_end_id: str,
        name_generator: NameGenerator,
        device: MINTDevice,
    ) -> None:
        cn_start = self._construction_nodes[cn_start_id]
        start_point = cn_start.output_options[0]

        cn_end = self._construction_nodes[cn_end_id]
        end_point = cn_end.input_options[0]

        if start_point.component_name is None:
            # This means a single component was mapped here
            src_component_name = self._component_refs[cn_start_id][0]
        else:
            src_component_name = name_generator.get_cn_name(
                cn_start_id, start_point.component_name)

        if end_point.component_name is None:
            # This means a single component was mapped here
            tar_component_name = self._component_refs[cn_end_id][0]
        else:
            tar_component_name = name_generator.get_cn_name(
                cn_end_id, end_point.component_name)

        # TODO - Change how we retrieve the technology type for the channel
        tech_string = "CHANNEL"
        # channel_name = name_generator.generate_name(tech_string)

        # TODO - Figure out how to hande a scenario where this isn't ture
        assert len(end_point.component_port) == 1
        if len(start_point.component_port) == 0:
            channel_name = name_generator.generate_name(tech_string)
            source = MINTTarget(src_component_name, None)
            sink = MINTTarget(tar_component_name, end_point.component_port[0])
            device.create_mint_connection(channel_name, tech_string,
                                          {"channelWidth": 400}, source,
                                          [sink], "0")
        else:
            for component_port in start_point.component_port:
                channel_name = name_generator.generate_name(tech_string)
                source = MINTTarget(src_component_name, component_port)
                sink = MINTTarget(tar_component_name,
                                  end_point.component_port[0])
                # TODO - Figure out how to make this layer generate automatically
                device.create_mint_connection(
                    channel_name,
                    tech_string,
                    {"channelWidth": 400},
                    source,
                    [sink],
                    "0",
                )

        # TODO - Once we are done creating a path, we need to delete the start and end point options
        # from their respective construction nodes.
        print("Updated the connectionoptions in {} - Removing {}".format(
            cn_start, start_point))
        cn_start.output_options.remove(start_point)

        print("Updated the connectionoptions in {} - Removing {}".format(
            cn_end, end_point))
        cn_end.input_options.remove(end_point)
Esempio n. 17
0
 def enterNetlist(self, ctx: mintParser.NetlistContext):
     self.current_device = MINTDevice("DEFAULT_NAME")
Esempio n. 18
0
def print_netlist(device: MINTDevice) -> None:
    # Generate the MINT file from the pyparchmint device
    minttext = device.to_MINT()
    mint_file = open(get_ouput_path(device.name + ".mint"), "wt")
    mint_file.write(minttext)
    mint_file.close()