libreda_db/hierarchy/
traits.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//! Basic traits that for the representation of chip data structures.
7
8#![allow(unused_variables)]
9#![allow(missing_docs)] // Necessary because portrait does not generate docs.
10
11use crate::prelude::PropertyValue;
12use crate::traits::{IdType, IdTypeMT};
13use std::borrow::Borrow;
14use std::hash::Hash;
15
16/// Identifier types used for components of hierarchical netlists and layouts.
17#[portrait::make]
18pub trait HierarchyIds {
19    /// Cell/module identifier type.
20    type CellId: IdType;
21    /// Cell instance identifier type.
22    type CellInstId: IdType;
23}
24
25/// Helper trait which constrains [`trait@HierarchyBase`] for such that ID types
26/// are [`Send`] and [`Sync`] as commonly used for parallel algorithms.
27#[portrait::make]
28pub trait HierarchyBaseMT:
29    HierarchyBase<CellId = Self::CellIdMT, CellInstId = Self::CellInstIdMT> + Sync
30{
31    /// Identifier type for cells.
32    type CellIdMT: IdTypeMT;
33    /// Identifier type for cell instances.
34    type CellInstIdMT: IdTypeMT;
35}
36
37impl<H> HierarchyBaseMT for H
38where
39    H: HierarchyBase + Sync,
40    H::CellId: Send + Sync,
41    H::CellInstId: Send + Sync,
42{
43    type CellIdMT = H::CellId;
44    type CellInstIdMT = H::CellInstId;
45}
46
47/// Most basic trait for the hierarchical flyweight pattern which is
48/// used to efficiently represent chip layouts and netlists.
49///
50/// ## Component relations
51///
52/// A netlist consists of cells which are templates for cell instances.
53/// Each cell may contain such instances of other cells.
54///
55/// The following diagram illustrates how this composition graph can be traversed using the functions
56/// defined by `HierarchyBase`.
57///
58/// ```txt
59///                          each_cell_dependency
60///                      +---------------------------+
61///                      |                           |
62///                      +                           v
63///       +----------------+   each_dependent_cell  +------------------+
64///       |Circuit (Top)   |<----------------------+|Circuit (Sub)     |
65///       +----------------+                        +------------------+
66///       |+              ^|                        | ^   +            |
67///       ||each_instance ||                        | |   |            |
68///       ||              ||                        | |   |            |
69///       ||              |parent                   | |   |            |
70///       ||              ||                        | |   |            |
71///       ||+-----------+ ||                        | |   |            |
72///  +--> |>|Inst1 (Sub)|-+|                        | |   |            |
73///  |    ||+-----------+  |                        | |   |            |
74///  |    ||               |                        | |   |            |
75///  |    ||               |                        +-|---|------------+
76///  |    ||               |                          |   |
77///  |    ||+-----------+  |  template                |   |
78///  +--> |>|Inst2 (Sub)|+----------------------------+   |
79///  |    | +-----------+  |                              |
80///  |    |                |                              |
81///  |    |                |                              |
82///  |    +----------------+                              |
83///  |                                                    |
84///  |                         each_reference             |
85///  +----------------------------------------------------+
86/// ```
87///
88/// # Example
89///
90/// Basic hierchy operations:
91///
92/// ```
93/// use libreda_db::chip::Chip;
94/// use libreda_db::traits::{HierarchyBase, HierarchyEdit};
95///
96/// // Create a simple hierarchical structure.
97/// let mut chip = Chip::new();
98/// let top_cell = chip.create_cell("MyTopCell".into());
99/// let sub_cell = chip.create_cell("MySubCell".into());
100/// // Create an instance of `sub_cell` inside `top_cell`.
101/// let inst = chip.create_cell_instance(&top_cell, &sub_cell, Some("inst1".into()));
102///
103/// // Get all cells.
104/// assert_eq!(chip.each_cell().count(), 2);
105///
106/// // Iterate over child instances.
107/// assert_eq!(chip.each_cell_instance(&top_cell).next().as_ref(), Some(&inst));
108///
109/// // Get the template of an instance.
110/// assert_eq!(&chip.template_cell(&inst), &sub_cell);
111///
112/// // Get the parent of an instance.
113/// assert_eq!(&chip.parent_cell(&inst), &top_cell);
114/// ```
115#[portrait::make(import(crate::prelude::PropertyValue))]
116pub trait HierarchyBase: HierarchyIds {
117    /// Type for names of cells, instances, etc.
118    type NameType: Eq
119        + Hash
120        + From<String>
121        + Into<String>
122        + Clone
123        + Borrow<String>
124        + Borrow<str>
125        + PartialOrd
126        + Ord
127        + std::fmt::Display
128        + std::fmt::Debug;
129
130    /// Find a cell by its name.
131    /// Return the cell with the given name. Returns `None` if the cell does not exist.
132    fn cell_by_name(&self, name: &str) -> Option<Self::CellId>;
133
134    /// Find a cell instance by its name.
135    /// Returns `None` if the name does not exist.
136    fn cell_instance_by_name(
137        &self,
138        parent_cell: &Self::CellId,
139        name: &str,
140    ) -> Option<Self::CellInstId>;
141
142    /// Get the name of the cell.
143    fn cell_name(&self, cell: &Self::CellId) -> Self::NameType;
144
145    /// Get the name of the cell instance.
146    fn cell_instance_name(&self, cell_inst: &Self::CellInstId) -> Option<Self::NameType>;
147
148    /// Get the ID of the parent cell of this instance.
149    fn parent_cell(&self, cell_instance: &Self::CellInstId) -> Self::CellId;
150
151    /// Get the ID of the template cell of this instance.
152    fn template_cell(&self, cell_instance: &Self::CellInstId) -> Self::CellId;
153
154    /// Call a function on each cell of the netlist.
155    fn for_each_cell<F>(&self, f: F)
156    where
157        F: FnMut(Self::CellId);
158
159    /// Get a `Vec` of all cell IDs in this netlist.
160    fn each_cell_vec(&self) -> Vec<Self::CellId> {
161        let mut v = Vec::new();
162        self.for_each_cell(|c| v.push(c));
163        v
164    }
165
166    /// Iterate over all cells.
167    fn each_cell(&self) -> Box<dyn Iterator<Item = Self::CellId> + '_> {
168        Box::new(self.each_cell_vec().into_iter())
169    }
170
171    /// Call a function on each instance in this cell.
172    fn for_each_cell_instance<F>(&self, cell: &Self::CellId, f: F)
173    where
174        F: FnMut(Self::CellInstId);
175
176    /// Get a `Vec` of the IDs of all instances in this cell.
177    fn each_cell_instance_vec(&self, cell: &Self::CellId) -> Vec<Self::CellInstId> {
178        let mut v = Vec::new();
179        self.for_each_cell_instance(cell, |c| v.push(c));
180        v
181    }
182
183    /// Iterate over all instances in a cell.
184    fn each_cell_instance(
185        &self,
186        cell: &Self::CellId,
187    ) -> Box<dyn Iterator<Item = Self::CellInstId> + '_> {
188        Box::new(self.each_cell_instance_vec(cell).into_iter())
189    }
190
191    /// Call a function for each cell that is a child of this `cell`.
192    fn for_each_cell_dependency<F>(&self, cell: &Self::CellId, f: F)
193    where
194        F: FnMut(Self::CellId);
195
196    /// Get a `Vec` of each cell that is a child of this `cell`.
197    fn each_cell_dependency_vec(&self, cell: &Self::CellId) -> Vec<Self::CellId> {
198        let mut v = Vec::new();
199        self.for_each_cell_dependency(cell, |c| v.push(c));
200        v
201    }
202
203    /// Iterate over all cells that are instantiated in this `cell`.
204    fn each_cell_dependency<'a>(
205        &'a self,
206        cell: &Self::CellId,
207    ) -> Box<dyn Iterator<Item = Self::CellId> + 'a> {
208        Box::new(self.each_cell_dependency_vec(cell).into_iter())
209    }
210
211    /// Count all cells that are dependencies of `cell`.
212    fn num_cell_dependencies(&self, cell: &Self::CellId) -> usize {
213        // Inefficient default implementation.
214        let mut counter = 0;
215        self.for_each_cell_dependency(cell, |_| counter += 1);
216        counter
217    }
218
219    /// Call a function for each cell that directly depends on `cell`.
220    fn for_each_dependent_cell<F>(&self, cell: &Self::CellId, f: F)
221    where
222        F: FnMut(Self::CellId);
223
224    /// Get a `Vec` of each cell that directly depends on `cell`.
225    fn each_dependent_cell_vec(&self, cell: &Self::CellId) -> Vec<Self::CellId> {
226        let mut v = Vec::new();
227        self.for_each_dependent_cell(cell, |c| v.push(c));
228        v
229    }
230
231    /// Iterate over each cell that directly depends on `cell`.
232    fn each_dependent_cell<'a>(
233        &'a self,
234        cell: &Self::CellId,
235    ) -> Box<dyn Iterator<Item = Self::CellId> + 'a> {
236        Box::new(self.each_dependent_cell_vec(cell).into_iter())
237    }
238
239    /// Count all cells that are directly dependent on `cell`, i.e. contain an instance of `cell`.
240    fn num_dependent_cells(&self, cell: &Self::CellId) -> usize {
241        // Inefficient default implementation.
242        let mut counter = 0;
243        self.for_each_dependent_cell(cell, |_| counter += 1);
244        counter
245    }
246
247    /// Iterate over all instances of this `cell`, i.e. instances that use this cell as
248    /// a template.
249    fn for_each_cell_reference<F>(&self, cell: &Self::CellId, f: F)
250    where
251        F: FnMut(Self::CellInstId);
252
253    /// Get a `Vec` with all cell instances referencing this cell.
254    fn each_cell_reference_vec(&self, cell: &Self::CellId) -> Vec<Self::CellInstId> {
255        let mut v = Vec::new();
256        self.for_each_cell_reference(cell, |c| v.push(c));
257        v
258    }
259
260    /// Iterate over all instances of this `cell`, i.e. instances that use this cell as
261    /// a template.
262    fn each_cell_reference(
263        &self,
264        cell: &Self::CellId,
265    ) -> Box<dyn Iterator<Item = Self::CellInstId> + '_> {
266        // Provide an inefficient default implementation.
267        Box::new(self.each_cell_reference_vec(cell).into_iter())
268    }
269
270    /// Count all instantiations of `cell`.
271    fn num_cell_references(&self, cell: &Self::CellId) -> usize {
272        // Inefficient default implementation.
273        let mut counter = 0;
274        self.for_each_cell_reference(cell, |_| counter += 1);
275        counter
276    }
277
278    /// Get the number of cell instances inside the `cell`.
279    fn num_child_instances(&self, cell: &Self::CellId) -> usize;
280
281    /// Get the number of cell templates.
282    fn num_cells(&self) -> usize;
283
284    /// Get a property of the top-level chip data structure.
285    fn get_chip_property(&self, key: &Self::NameType) -> Option<PropertyValue> {
286        None
287    }
288
289    /// Get a property of a cell.
290    fn get_cell_property(
291        &self,
292        cell: &Self::CellId,
293        key: &Self::NameType,
294    ) -> Option<PropertyValue> {
295        None
296    }
297
298    /// Get a property of a cell instance.
299    fn get_cell_instance_property(
300        &self,
301        inst: &Self::CellInstId,
302        key: &Self::NameType,
303    ) -> Option<PropertyValue> {
304        None
305    }
306}
307
308/// Edit functions for a hierarchical flyweight structure like a netlist or a cell-based layout.
309#[portrait::make(import(crate::prelude::PropertyValue))]
310pub trait HierarchyEdit: HierarchyBase {
311    ///// Create a new empty data structure.
312    //fn new() -> Self;
313
314    /// Create a new and empty cell template.
315    /// A cell template can be be instantiated in other cells.
316    ///
317    /// # Example
318    /// ```
319    /// use libreda_db::prelude::*;
320    /// let mut chip = Chip::new();
321    /// let my_cell = chip.create_cell("myCell".into());
322    ///
323    /// assert_eq!(chip.num_cells(), 1);
324    /// assert_eq!(chip.cell_by_name("myCell"), Some(my_cell));
325    /// ```
326    fn create_cell(&mut self, name: Self::NameType) -> Self::CellId;
327
328    /// Remove a cell and all the instances of it.
329    ///
330    /// # Example
331    /// ```
332    /// use libreda_db::prelude::*;
333    /// let mut chip = Chip::new();
334    /// let top = chip.create_cell("TOP".into());
335    /// assert_eq!(chip.num_cells(), 1);
336    /// chip.remove_cell(&top);
337    /// assert_eq!(chip.num_cells(), 0);
338    /// ```
339    fn remove_cell(&mut self, cell_id: &Self::CellId);
340
341    /// Create a new instance of `template_cell` in `parent_cell`.
342    /// Recursive instantiation is forbidden and might panic.
343    ///
344    /// # Example
345    /// ```
346    /// use libreda_db::prelude::*;
347    /// let mut chip = Chip::new();
348    /// let top = chip.create_cell("TOP".into());
349    /// let sub = chip.create_cell("SUB".into());
350    ///
351    /// // Create two instances of "SUB" inside "TOP".
352    /// let inst1 = chip.create_cell_instance(&top, &sub, Some("sub1".into())); // Create named instance.
353    /// let inst2 = chip.create_cell_instance(&top, &sub, None); // Create unnamed instance.
354    ///
355    /// assert_eq!(chip.num_child_instances(&top), 2);
356    /// assert_eq!(chip.num_cell_references(&sub), 2);
357    /// ```
358    fn create_cell_instance(
359        &mut self,
360        parent_cell: &Self::CellId,
361        template_cell: &Self::CellId,
362        name: Option<Self::NameType>,
363    ) -> Self::CellInstId;
364
365    /// Remove cell instance if it exists.
366    /// # Example
367    /// ```
368    /// use libreda_db::prelude::*;
369    /// let mut chip = Chip::new();
370    /// let top = chip.create_cell("TOP".into());
371    /// let sub = chip.create_cell("SUB".into());
372    ///
373    /// // Create two instances of "SUB" inside "TOP".
374    /// let inst1 = chip.create_cell_instance(&top, &sub, Some("sub1".into())); // Create named instance.
375    /// let inst2 = chip.create_cell_instance(&top, &sub, None); // Create unnamed instance.
376    ///
377    /// assert_eq!(chip.num_child_instances(&top), 2);
378    /// assert_eq!(chip.num_cell_references(&sub), 2);
379    ///
380    /// chip.remove_cell_instance(&inst2);
381    ///
382    /// assert_eq!(chip.num_child_instances(&top), 1);
383    /// assert_eq!(chip.num_cell_references(&sub), 1);
384    /// ```
385    fn remove_cell_instance(&mut self, inst: &Self::CellInstId);
386
387    /// Change the name of a cell instance.
388    ///
389    /// Clears the name when `None` is passed.
390    ///
391    /// # Panics
392    /// Panics if an instance with this name already exists in the parent cell.
393    fn rename_cell_instance(&mut self, inst: &Self::CellInstId, new_name: Option<Self::NameType>);
394
395    /// Change the name of a cell.
396    ///
397    /// # Panics
398    /// Panics if a cell with this name already exists.
399    fn rename_cell(&mut self, cell: &Self::CellId, new_name: Self::NameType);
400
401    /// Set a property of the top-level chip data structure..
402    fn set_chip_property(&mut self, key: Self::NameType, value: PropertyValue) {}
403
404    /// Set a property of a cell.
405    fn set_cell_property(
406        &mut self,
407        cell: &Self::CellId,
408        key: Self::NameType,
409        value: PropertyValue,
410    ) {
411    }
412
413    /// Set a property of a cell instance.
414    fn set_cell_instance_property(
415        &mut self,
416        inst: &Self::CellInstId,
417        key: Self::NameType,
418        value: PropertyValue,
419    ) {
420    }
421}