Skip to content

Instantly share code, notes, and snippets.

@rkrishnasanka
Last active January 28, 2021 13:55
Show Gist options
  • Save rkrishnasanka/8fa9eb58c28c6743f0950a4ac86d952e to your computer and use it in GitHub Desktop.
Save rkrishnasanka/8fa9eb58c28c6743f0950a4ac86d952e to your computer and use it in GitHub Desktop.
Parchmint import pseudocode
def apply_layout(self):
device = self.__original_device
for ID in self.cells.keys():
component = device.get_component(ID)
cell = self.cells[ID]
component.params.set_param("position", [cell.x, cell.y])
for ID in self.nets.keys():
connection = device.get_connection(ID)
net = self.nets[ID]
for route in net.routes:
path = []
for vertex in route.waypoints:
path.append((vertex.x, vertex.y))
connection.add_waypoints_path(None, None, path)
print(
"Updating connection: {} with path {}".format(
connection.ID, str(path)
)
)
def importMINTwithoutConstraints(self, device: MINTDevice) -> None:
self.__original_device = device
pcells = []
for component in device.components:
terminals = []
for port in component.ports:
t = CTerminal(
port.label,
floor(port.x / parameters.LAMBDA),
floor(port.y / parameters.LAMBDA),
)
print("Before Update: ({}, {})".format(t.x, t.y))
t.compute_absolute_positions(
floor(component.xpos / parameters.LAMBDA),
floor(component.ypos / parameters.LAMBDA),
)
print("After Update: ({}, {})".format(t.x, t.y))
terminals.append(t)
if component.params.exists("componentSpacing"):
component_spacing = component.params.get_param("componentSpacing")
else:
component_spacing = 1000 # Some random value
pcell = CCell(
component.ID,
round(component.xpos / parameters.LAMBDA),
round(component.ypos / parameters.LAMBDA),
round(component.xspan / parameters.LAMBDA),
round(component.yspan / parameters.LAMBDA),
round(component_spacing / parameters.LAMBDA),
terminals,
)
pcells.append(pcell)
self.cells[pcell.id] = pcell
for connection in device.connections:
id = connection.ID
source = self.cells[connection.source.component]
source_terminal = None
if connection.source.port is not None:
# Get C Terminal for this
try:
source_terminal = get_terminal(source, connection.source.port)
# source_terminal = source.get_terminal(connection.source.port)
except Exception:
print(
"Could not find Terminal for source port: {} {} for connection: {}".format(
source.id, connection.source.port, id
)
)
else:
if len(source.ports) == 1:
print('Assigning "1" as the default terminal for net')
# source_terminal = get_terminal(source, "1")
source_terminal = source.ports[0]
else:
raise Exception(
"No scheme for handling scenarios where no source port is defined and there's more than 1 port available"
)
source_terminal = None
sink_cells = []
sink_terminals = []
for sink in connection.sinks:
pcell = self.cells[sink.component]
sink_cells.append(pcell)
if sink.port is not None:
try:
t = get_terminal(pcell, sink.port)
sink_terminals.append(t)
except Exception:
print(
"Could not find Terminal for source port: {} for connection: {}".format(
source.id, id
)
)
else:
if len(pcell.ports) == 1:
print('Assigning "1" as the default terminal for net')
# t = get_terminal(pcell, "1")
t = pcell.ports[0]
sink_terminals.append(t)
else:
raise Exception(
"No scheme for handling scenarios where no source port is defined and there's more than 1 port available"
)
sink_terminals.append(None)
# cnet.sinks = sink_cells
# cnet.sink_terminals = sink_terminals
cnet = CNet()
cnet.id = id
cnet.source = source
cnet.source_terminal = source_terminal
width = connection.params.get_param("channelWidth")
cnet.channelWidth = width
spacing = 2 * width
cnet.channelSpacing = spacing
# TODO - Figure out how to fix the interface later
for sink_cell in sink_cells:
cnet.sinks.append(sink_cell)
# TODO - Figure out how to fix the interface later
for sink_terminal in sink_terminals:
cnet.sink_terminals.append(sink_terminal)
self.nets[cnet.id] = cnet
all_routes = []
obstacle_check_vertices = []
for net in list(self.nets.values()):
# Just get a single source and sink
source_vertex = Vertex()
source_vertex.x = net.source_terminal.x
source_vertex.y = net.source_terminal.y
obstacle_check_vertices.append(source_vertex)
for sink_terminal in net.sink_terminals:
target_vertex = Vertex()
target_vertex.x = sink_terminal.x
target_vertex.y = sink_terminal.y
obstacle_check_vertices.append(target_vertex)
route = Route(
net.id,
source_vertex,
target_vertex,
net.channelWidth,
net.channelSpacing,
)
# r = Route(net.ID, source_vertex, target_vertex)
all_routes.append(route)
# TODO - FIX THIS LATER
net.routes.append(route)
obstacles = []
# Step 2 - generate the obstacles from the components
for ID, cell in list(self.cells.items()):
# TODO - CHECK IF ANY OF THE ROUTES HAVE THESE AS THE INPUTS/OUTPUTS
overlaps_vertex = False
for vertex in obstacle_check_vertices:
overlaps_vertex = overlaps_vertex or inside_obstabcle(vertex, cell)
if overlaps_vertex:
break
if overlaps_vertex is False:
obstacle = Obstacle()
obstacle.x = cell.x + 1
obstacle.y = cell.y + 1
obstacle.x_span = cell.x_span - 1
obstacle.y_span = cell.y_span - 1
obstacles.append(obstacle)
# Step 3 - Do the routing
router = AARFRouter(obstacles)
router.route(all_routes, 0, 0, parameters.DEVICE_X_DIM, parameters.DEVICE_Y_DIM)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment