1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
// Copyright (c) 2020-2021 Thomas Kramer.
// SPDX-FileCopyrightText: 2022 Thomas Kramer <code@tkramer.ch>
//
// SPDX-License-Identifier: AGPL-3.0-or-later
//! Trait definitions for mixed-size placement algorithms.
//! Mixed-size placers find positions for macro block and standard-cells.
use db::L2NBase;
pub use libreda_db::prelude as db;
pub use libreda_db::prelude::{SInt, TryCastCoord, UInt, WindingNumber};
use super::placement_problem::PlacementProblem;
pub use libreda_db::iron_shapes::prelude::{Point, SimpleRPolygon};
use std::collections::HashMap;
/// Error type used for global placement.
#[derive(Debug)]
pub enum PlacementError {
/// Stopped placement algorithm because the maximal number of iterations was reached.
ReachedMaxIterations,
/// The solution diverges. This is likely a bug in the placement algorithm.
Divergence,
/// Other type of error. Defined by an error message string.
Other(String),
}
impl std::fmt::Display for PlacementError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
PlacementError::ReachedMaxIterations => {
write!(f, "Reached maximum number of iterations.")
}
PlacementError::Divergence => write!(f, "Placement diverges."),
PlacementError::Other(s) => write!(f, "{}", s),
}
}
}
impl std::error::Error for PlacementError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
None
}
}
/// Interface definition for mixed-size placement engines (for macro blocks and standard cells).
pub trait MixedSizePlacer<C: L2NBase> {
/// Get the name of the placement engine.
fn name(&self) -> &str;
/// Actual implementation of [`MixedSizePlacer::find_cell_positions`].
fn find_cell_positions_impl(
&self,
placement_problem: &dyn PlacementProblem<C>,
) -> Result<HashMap<C::CellInstId, db::SimpleTransform<C::Coord>>, PlacementError>;
/// Find the positions of all circuit instances inside `circuit`.
///
/// # Parameters
///
/// * `placement_problem`: [`PlacementProblem`] trait object. This object bundles the netlist, layout and
/// other parameters relevant for placement such as cell-sizes, fixed/movable cells, net weights.
///
/// # Returns
///
/// Returns a `HashMap` which maps circuit instances to positions.
fn find_cell_positions(
&self,
placement_problem: &dyn PlacementProblem<C>,
) -> Result<HashMap<C::CellInstId, db::SimpleTransform<C::Coord>>, PlacementError> {
self.find_cell_positions_impl(placement_problem)
}
}