libreda_db/technology/
layerstack.rs1use super::rules::RuleBase;
9
10#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
12pub enum RoutingLayerType {
13 Cut,
15 Routing,
17}
18
19#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
21pub struct RoutingLayer<LayerId> {
22 pub id: LayerId,
24 pub layer_type: RoutingLayerType,
26}
27
28impl<LayerId> RoutingLayer<LayerId> {
29 pub fn new(id: LayerId, layer_type: RoutingLayerType) -> Self {
31 Self { id, layer_type }
32 }
33
34 pub fn as_id(&self) -> &LayerId {
36 &self.id
37 }
38
39 pub fn id(self) -> LayerId {
41 self.id
42 }
43
44 pub fn layer_type(&self) -> RoutingLayerType {
46 self.layer_type
47 }
48
49 pub fn is_via_layer(&self) -> bool {
51 match self.layer_type() {
52 RoutingLayerType::Cut => true,
53 RoutingLayerType::Routing => false,
54 }
55 }
56
57 pub fn is_metal_layer(&self) -> bool {
59 match self.layer_type() {
60 RoutingLayerType::Cut => false,
61 RoutingLayerType::Routing => true,
62 }
63 }
64}
65
66pub trait RoutingLayerStack: RuleBase {
68 fn layer_stack(&self) -> Vec<RoutingLayer<Self::LayerId>>;
70
71 fn layer_stack_ids(&self) -> Vec<Self::LayerId> {
73 self.layer_stack().into_iter().map(|l| l.id).collect()
74 }
75
76 fn routing_layer_stack(&self) -> Vec<Self::LayerId> {
78 self.layer_stack()
79 .into_iter()
80 .filter(|l| l.is_metal_layer())
81 .map(|l| l.id())
82 .collect()
83 }
84
85 fn via_layer_stack(&self) -> Vec<Self::LayerId> {
87 self.layer_stack()
88 .into_iter()
89 .filter(|l| l.is_via_layer())
90 .map(|l| l.id())
91 .collect()
92 }
93
94 fn get_upper_metal_layer(&self, layer: &Self::LayerId) -> Option<Self::LayerId> {
96 self.layer_stack()
97 .into_iter()
98 .skip_while(|l| l.as_id() != layer)
99 .skip(1)
100 .find(|l| l.is_metal_layer())
101 .map(|l| l.id())
102 }
103
104 fn get_lower_metal_layer(&self, layer: &Self::LayerId) -> Option<Self::LayerId> {
106 self.layer_stack()
107 .into_iter()
108 .rev()
109 .skip_while(|l| l.as_id() != layer)
110 .skip(1)
111 .find(|l| l.is_metal_layer())
112 .map(|l| l.id())
113 }
114}