ASIC place & route framework. This crate contains interface definitions of the core parts of the place & route flow.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

85 lines
3.2 KiB

// Copyright (c) 2020-2021 Thomas Kramer.
// SPDX-FileCopyrightText: 2022 Thomas Kramer <code@tkramer.ch>
//
// SPDX-License-Identifier: AGPL-3.0-or-later
//! Representation of the placement problem.
//!
//! A trait based representation gives more flexibility than passing naked arguments
//! to the placement engine.
use libreda_db::prelude as db;
use std::collections::HashSet;
/// Describe the placement status of a cell instance.
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
pub enum PlacementStatus {
/// The instance location is fixed and must remain.
Fixed,
/// The instance can be put into another location by the placement engine.
Movable,
/// The instance should be ignored by the placement engine.
Ignore,
}
/// Representation of the placement task.
pub trait PlacementProblem<C: db::L2NBase> {
/// Get the base layout/netlist structure.
fn fused_layout_netlist(&self) -> &C;
/// Get the top cell whose content should be placed.
fn top_cell(&self) -> C::CellId;
/// Get a list of polygons which describe where cells are allowed to be placed.
fn placement_region(&self) -> Vec<db::SimpleRPolygon<C::Coord>>;
/// Get regions which should not be used for placement but can if necessary.
/// Overlap of cells with this regions should be minimized.
fn soft_blockages(&self) -> Vec<db::SimpleRPolygon<C::Coord>> {
vec![]
}
/// Get the position of a cell instance which should be used as an initial value
/// for the optimization.
/// This is most likely the output of the previous placement step.
fn initial_position(&self, cell_instance: &C::CellInstId) -> db::SimpleTransform<C::Coord>;
/// Tell if the cell instance can be moved by the placement engine.
fn placement_status(&self, cell_instance: &C::CellInstId) -> PlacementStatus;
/// Get the abutment box / outline of the cell.
fn cell_outline(&self, cell: &C::CellId) -> Option<db::Rect<C::Coord>>;
/// Get the abutment box / outline of the cell instance.
fn cell_instance_outline(&self, cell_instance: &C::CellInstId) -> Option<db::Rect<C::Coord>> {
let template = self.fused_layout_netlist().template_cell(cell_instance);
self.cell_outline(&template)
}
/// Get the weight of a net. Default is `1.0`.
/// When optimizing the wire-length, the *weighted* wire-length should be used.
/// For example a weight `0.0` means that the net should not be considered for wire-length optimization.
fn net_weight(&self, _net: &C::NetId) -> f64 {
1.0
}
/// TODO: fn arc_weight(&self, arc: &ArcId<C>) -> f64;
/// Get the set of fixed instances.
fn get_fixed_instances(&self) -> HashSet<C::CellInstId> {
self.fused_layout_netlist()
.each_cell_instance(&self.top_cell())
.filter(|inst| self.placement_status(inst) == PlacementStatus::Fixed)
.collect()
}
/// Get the set of movable cell instances.
fn get_movable_instances(&self) -> HashSet<C::CellInstId> {
self.fused_layout_netlist()
.each_cell_instance(&self.top_cell())
.filter(|inst| self.placement_status(inst) == PlacementStatus::Movable)
.collect()
}
}