libreda_db/reference_access/
hierarchy_reference_access.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
6use crate::traits::HierarchyBase;
7
8/// Trait that provides object-like read access to a cell hierarchy structure and its elements.
9pub trait HierarchyReferenceAccess: HierarchyBase {
10    /// Iterate over all cell objects.
11    fn each_cell_ref(&self) -> Box<dyn Iterator<Item = CellRef<Self>> + '_> {
12        Box::new(self.each_cell().map(move |id| self.cell_ref(&id)))
13    }
14
15    /// Get a cell object by its ID.
16    fn cell_ref(&self, cell_id: &Self::CellId) -> CellRef<'_, Self> {
17        CellRef {
18            base: self,
19            id: cell_id.clone(),
20        }
21    }
22
23    /// Get a cell instance object by its ID.
24    fn cell_instance_ref(&self, inst_id: &Self::CellInstId) -> CellInstRef<'_, Self> {
25        CellInstRef {
26            base: self,
27            id: inst_id.clone(),
28        }
29    }
30}
31
32impl<T: HierarchyBase> HierarchyReferenceAccess for T {}
33
34/// A reference to a cell.
35/// This is just a wrapper around a netlist and a cell ID.
36pub struct CellRef<'a, H: HierarchyBase + ?Sized> {
37    /// Reference to the parent data structure.
38    pub(super) base: &'a H,
39    /// ID of the corresponding cell.
40    pub(super) id: H::CellId,
41}
42
43impl<'a, H: HierarchyBase> Eq for CellRef<'a, H> {}
44impl<'a, H: HierarchyBase> PartialEq for CellRef<'a, H> {
45    fn eq(&self, other: &Self) -> bool {
46        self.id == other.id && std::ptr::eq(self.base, other.base)
47    }
48}
49
50impl<'a, H: HierarchyBase> std::fmt::Debug for CellRef<'a, H> {
51    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
52        write!(f, "CellRef({})", self.name())
53    }
54}
55
56// impl<'a, H: HierarchyBase> AsRef<H> for CellRef<'a, H> {
57//     fn as_ref(&self) -> &H {
58//         self.base
59//     }
60// }
61//
62//
63// impl<'a, H: HierarchyBase> Deref for CellRef<'a, H> {
64//     type Target = H;
65//
66//     fn deref(&self) -> &Self::Target {
67//         self.base
68//     }
69// }
70
71impl<'a, H: HierarchyBase> Clone for CellRef<'a, H> {
72    fn clone(&self) -> Self {
73        Self {
74            base: self.base,
75            id: self.id.clone(),
76        }
77    }
78}
79
80impl<'a, H: HierarchyBase> CellRef<'a, H> {
81    /// Access the base structure.
82    pub fn base(&self) -> &'_ H {
83        self.base
84    }
85
86    /// Get the ID of this cell.
87    pub fn id(&self) -> H::CellId {
88        self.id.clone()
89    }
90
91    /// Get the name of the cell.
92    pub fn name(&self) -> H::NameType {
93        self.base.cell_name(&self.id)
94    }
95
96    /// Iterate over the IDs of all child instances.
97    pub fn each_cell_instance_id(&self) -> impl Iterator<Item = H::CellInstId> + '_ {
98        self.base.each_cell_instance(&self.id)
99    }
100
101    /// Iterate over all child instances.
102    pub fn each_cell_instance(&self) -> impl Iterator<Item = CellInstRef<'a, H>> + '_ {
103        self.each_cell_instance_id().map(move |id| CellInstRef {
104            base: self.base,
105            id,
106        })
107    }
108
109    /// Find a child instance by its name.
110    pub fn cell_instance_by_name(&self, name: &str) -> Option<CellInstRef<'a, H>> {
111        self.base
112            .cell_instance_by_name(&self.id, name)
113            .map(|id| CellInstRef {
114                base: self.base,
115                id,
116            })
117    }
118
119    /// Iterate over the IDs of all instances of this cell.
120    pub fn each_reference_id(&self) -> impl Iterator<Item = H::CellInstId> + '_ {
121        self.base.each_cell_reference(&self.id)
122    }
123
124    /// Iterate over the of all instances of this cell.
125    pub fn each_reference(&self) -> impl Iterator<Item = CellInstRef<'a, H>> + '_ {
126        self.each_reference_id().map(move |id| CellInstRef {
127            base: self.base,
128            id,
129        })
130    }
131
132    /// Get the total number of usages of this cell.
133    pub fn num_references(&self) -> usize {
134        self.base.num_cell_references(&self.id)
135    }
136
137    /// Iterate over all dependencies of this cell.
138    pub fn each_cell_dependency(&self) -> impl Iterator<Item = CellRef<'a, H>> + '_ {
139        self.base
140            .each_cell_dependency(&self.id)
141            .map(move |id| CellRef {
142                base: self.base,
143                id,
144            })
145    }
146
147    /// Get the total number of direct dependencies of this cell.
148    pub fn num_cell_dependencies(&self) -> usize {
149        self.base.num_cell_dependencies(&self.id)
150    }
151
152    /// Iterate over all cells that directly depend on this cell.
153    pub fn each_dependent_cell(&self) -> impl Iterator<Item = CellRef<'a, H>> + '_ {
154        self.base
155            .each_dependent_cell(&self.id)
156            .map(move |id| CellRef {
157                base: self.base,
158                id,
159            })
160    }
161
162    /// Get the total number of cells which depend on this cell (i.e. use it).
163    pub fn num_dependent_cells(&self) -> usize {
164        self.base.num_dependent_cells(&self.id)
165    }
166
167    /// Get the number of cell instances inside the `cell`.
168    pub fn num_child_instances(&self) -> usize {
169        self.base.num_child_instances(&self.id)
170    }
171}
172
173/// Default implementation for `CellInstRef`.
174/// This is just a wrapper around a netlist and a cell ID.
175pub struct CellInstRef<'a, H: HierarchyBase + ?Sized> {
176    /// Reference to the parent netlist.
177    pub(super) base: &'a H,
178    /// ID of the corresponding cell instance.
179    pub(super) id: H::CellInstId,
180}
181
182impl<'a, H: HierarchyBase> Eq for CellInstRef<'a, H> {}
183impl<'a, H: HierarchyBase> PartialEq for CellInstRef<'a, H> {
184    fn eq(&self, other: &Self) -> bool {
185        self.id == other.id && std::ptr::eq(self.base, other.base)
186    }
187}
188
189impl<'a, H: HierarchyBase> std::fmt::Debug for CellInstRef<'a, H> {
190    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
191        write!(f, "CellInstRef({})", self.qname(":"))
192    }
193}
194
195impl<'a, H: HierarchyBase> CellInstRef<'a, H> {
196    /// Access the base structure.
197    pub fn base(&self) -> &'_ H {
198        self.base
199    }
200
201    /// Get the ID of this cell instance.
202    pub fn id(&self) -> H::CellInstId {
203        self.id.clone()
204    }
205
206    /// Get the name of the cell instance.
207    pub fn name(&self) -> Option<H::NameType> {
208        self.base.cell_instance_name(&self.id)
209    }
210
211    /// Get a qualified name for this instance.
212    pub fn qname(&self, separator: &str) -> String {
213        format!(
214            "{}{}{}",
215            self.parent().name(),
216            separator,
217            self.name()
218                .unwrap_or_else(|| "<unnamed>".to_string().into())
219        )
220    }
221
222    /// Get the parent cell of this instance.
223    pub fn parent(&self) -> CellRef<'a, H> {
224        CellRef {
225            base: self.base,
226            id: self.parent_id(),
227        }
228    }
229
230    /// Get the template cell of this instance.
231    pub fn template(&self) -> CellRef<'a, H> {
232        CellRef {
233            base: self.base,
234            id: self.template_id(),
235        }
236    }
237
238    /// Get the ID of the parent cell of this instance.
239    pub fn parent_id(&self) -> H::CellId {
240        self.base.parent_cell(&self.id)
241    }
242
243    /// Get the ID of the template cell of this instance.
244    pub fn template_id(&self) -> H::CellId {
245        self.base.template_cell(&self.id)
246    }
247}