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}