libreda_db/technology/
rules.rs

1// Copyright (c) 2020-2021 Thomas Kramer.
2// SPDX-FileCopyrightText: 2022 Thomas Kramer
3//
4// SPDX-License-Identifier: AGPL-3.0-or-later
5
6//! Traits that define how certain design rules are represented.
7//!
8//! TBD
9
10use crate::prelude::Orientation2D;
11use num_traits::Num;
12
13/// Define essential types used for expressing design rules.
14pub trait RuleBase {
15    /// Type used as layer identifier.
16    type LayerId: Eq + Clone;
17}
18
19/// Define essential types used for expressing design rules based on distance relations.
20pub trait DistanceRuleBase: RuleBase {
21    /// Type used to express distances.
22    type Distance: Num + Copy + PartialOrd;
23    /// Type used to express areas.
24    type Area: Num + Copy + PartialOrd;
25}
26
27/// Minimum spacing rules between shapes on the same layer.
28pub trait MinimumSpacing: DistanceRuleBase {
29    /// Absolute minimum spacing between two shapes on the `layer`.
30    fn min_spacing_absolute(&self, layer: &Self::LayerId) -> Option<Self::Distance>;
31
32    /// Minimum spacing between two shapes on the `layer` dependent on the geometries.
33    fn min_spacing(
34        &self,
35        layer: &Self::LayerId,
36        run_length: Self::Distance,
37        width: Self::Distance,
38    ) -> Option<Self::Distance>;
39
40    // Use another MinimumSpacing instance for same-net spacing.
41    // fn min_spacing_same_net(layer: &Self::LayerId) -> Self::Distance;
42}
43
44/// Minimum width rules.
45pub trait MinimumWidth: DistanceRuleBase {
46    /// Minimal width of a shape with a certain length.
47    fn min_width(
48        &self,
49        layer: &Self::LayerId,
50        shape_length: Option<Self::Distance>,
51    ) -> Option<Self::Distance>;
52}
53
54/// Default width rules.
55pub trait DefaultWidth: DistanceRuleBase {
56    /// Default width of a wire segment of a certain length.
57    fn default_width(
58        &self,
59        layer: &Self::LayerId,
60        shape_length: Option<Self::Distance>,
61    ) -> Option<Self::Distance>;
62}
63
64/// Preferred routing direction on metal layers.
65pub trait PreferredRoutingDirection: RuleBase {
66    /// Get the preferred routing direction on this metal layer.
67    fn preferred_routing_direction(&self, layer: &Self::LayerId) -> Option<Orientation2D>;
68}
69
70/// Rules commonly used for routing.
71pub trait RoutingRules:
72    PreferredRoutingDirection + DefaultWidth + MinimumSpacing + MinimumWidth
73{
74    /// Get the default routing pitch on this layer for x and y directions.
75    fn default_pitch(&self, layer: &Self::LayerId) -> Option<(Self::Distance, Self::Distance)>;
76
77    /// Get the default routing pitch for wires with the preferred routing direction.
78    /// Return `None` if no default pitch or no routing direction is defined for this layer.
79    fn default_pitch_preferred_direction(&self, layer: &Self::LayerId) -> Option<Self::Distance> {
80        let pitch = self.default_pitch(layer)?;
81        let preferred_direction = self.preferred_routing_direction(layer)?;
82
83        match preferred_direction {
84            Orientation2D::Horizontal => Some(pitch.1),
85            Orientation2D::Vertical => Some(pitch.0),
86        }
87    }
88}