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}