libreda_db/netlist/
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//! Traits for netlist data types.
7//!
8//! Instead of putting a netlist data structure into the center of the world,
9//! this data base concentrates on the way *how* a netlist can be accessed and modified.
10//! The basic necessary operations are defined in the [`NetlistBase'] trait and in the
11//! [`NetlistEdit`] trait.
12//!
13//! More complex operations on netlist are provided by the [`NetlistUtil`] and [`NetlistEditUtil`] traits.
14//!
15//! [`NetlistBase`]: trait@NetlistBase
16//! [`NetlistEdit`]: trait@NetlistEdit
17//! [`NetlistUtil`]: trait@crate::netlist::util::NetlistUtil
18//! [`NetlistEditUtil`]: trait@crate::netlist::util::NetlistEditUtil
19
20#![allow(missing_docs)] // Necessary because portrait does not generate docs.
21
22use super::prelude::*;
23pub use super::util::{NetlistEditUtil, NetlistUtil};
24pub use crate::traits::{HierarchyBase, HierarchyEdit};
25use crate::traits::{HierarchyBaseMT, HierarchyIds, IdType, IdTypeMT};
26
27/// Identifier types used for components of netlists.
28#[portrait::make]
29pub trait NetlistIds: HierarchyIds {
30    /// Pin identifier type. Uniquely identifies a pin in the whole netlist.
31    type PinId: IdType;
32    /// Pin instance identifier type. Uniquely identifies a pin instance in the whole netlist.
33    /// A pin instance is a pin of a circuit instance.
34    type PinInstId: IdType;
35    /// Net identifier type. Uniquely identifies a net in the whole netlist.
36    type NetId: IdType;
37}
38
39/// Helper trait which constrains [`trait@NetlistBase`] for such that ID types
40/// are [`Send`] and [`Sync`] as commonly used for parallel algorithms.
41#[portrait::make]
42pub trait NetlistBaseMT:
43    NetlistBase<PinId = Self::PinIdMT, PinInstId = Self::PinInstIdMT, NetId = Self::NetIdMT>
44    + HierarchyBaseMT
45{
46    /// ID of a pin.
47    type PinIdMT: IdTypeMT;
48    /// ID of a pin instance.
49    type PinInstIdMT: IdTypeMT;
50    /// ID of a net.
51    type NetIdMT: IdTypeMT;
52}
53
54impl<N> NetlistBaseMT for N
55where
56    N: NetlistBase + HierarchyBaseMT,
57    N::PinId: Send + Sync,
58    N::PinInstId: Send + Sync,
59    N::NetId: Send + Sync,
60{
61    type PinIdMT = N::PinId;
62    type PinInstIdMT = N::PinInstId;
63    type NetIdMT = N::NetId;
64}
65
66/// Most basic trait for traversing a netlist.
67/// A netlist extends the `HierarchyBase` and hence is hierarchical.
68/// `NetlistBase` extends the components of the hierarchy with pins and nets.
69/// Each cell can have pins. Each cell instance has pin instances that correspond one-to-one
70/// to the pins of the template cell. Cells can contain nets. Each pin and each pin instance can be
71/// connected to one or zero nets. A net can be connected to an arbitrary number of pins and pin instances.
72///
73/// Pins must have a name and also a signal direction.
74///
75/// Nets *can* have a name.
76///
77#[portrait::make(import(crate::prelude::Direction))]
78pub trait NetlistBase: HierarchyBase + NetlistIds {
79    /// Get the ID of the template pin of this pin instance.
80    fn template_pin(&self, pin_instance: &Self::PinInstId) -> Self::PinId;
81
82    /// Get the signal direction of the pin.
83    fn pin_direction(&self, pin: &Self::PinId) -> Direction;
84
85    /// Get the name of the pin.
86    fn pin_name(&self, pin: &Self::PinId) -> Self::NameType;
87
88    /// Find a pin by its name.
89    /// Returns `None` if no such pin can be found.
90    fn pin_by_name(&self, parent_circuit: &Self::CellId, name: &str) -> Option<Self::PinId>;
91
92    /// Get the ID of the parent circuit of this pin.
93    fn parent_cell_of_pin(&self, pin: &Self::PinId) -> Self::CellId;
94
95    /// Get the ID of the circuit instance that holds this pin instance.
96    fn parent_of_pin_instance(&self, pin_inst: &Self::PinInstId) -> Self::CellInstId;
97
98    /// Get the ID of a pin instance given the cell instance and the pin ID.
99    fn pin_instance(&self, cell_inst: &Self::CellInstId, pin: &Self::PinId) -> Self::PinInstId {
100        // Inefficient default implementation.
101        self.each_pin_instance(cell_inst)
102            .find(|inst| &self.template_pin(inst) == pin)
103            .expect("No such pin found in this cell.")
104    }
105
106    /// Get the ID of the parent circuit of this net.
107    fn parent_cell_of_net(&self, net: &Self::NetId) -> Self::CellId;
108
109    /// Get the internal net attached to this pin.
110    fn net_of_pin(&self, pin: &Self::PinId) -> Option<Self::NetId>;
111
112    /// Get the external net attached to this pin instance.
113    fn net_of_pin_instance(&self, pin_instance: &Self::PinInstId) -> Option<Self::NetId>;
114
115    /// Get the net of the logical constant zero.
116    fn net_zero(&self, parent_circuit: &Self::CellId) -> Self::NetId;
117
118    /// Get the net of the logical constant one.
119    fn net_one(&self, parent_circuit: &Self::CellId) -> Self::NetId;
120
121    /// Find a net by its name inside the parent circuit.
122    /// Returns `None` if no such net can be found.
123    fn net_by_name(&self, parent_circuit: &Self::CellId, name: &str) -> Option<Self::NetId>;
124
125    /// Get the name of the net.
126    fn net_name(&self, net: &Self::NetId) -> Option<Self::NameType>;
127
128    /// Call a function for each pin of the circuit.
129    fn for_each_pin<F>(&self, circuit: &Self::CellId, f: F)
130    where
131        F: FnMut(Self::PinId);
132
133    /// Get a `Vec` with the IDs of all pins of this circuit.
134    fn each_pin_vec(&self, circuit: &Self::CellId) -> Vec<Self::PinId> {
135        let mut v = Vec::new();
136        self.for_each_pin(circuit, |c| v.push(c));
137        v
138    }
139
140    /// Iterate over all pins of a circuit.
141    fn each_pin<'a>(
142        &'a self,
143        circuit: &Self::CellId,
144    ) -> Box<dyn Iterator<Item = Self::PinId> + 'a> {
145        Box::new(self.each_pin_vec(circuit).into_iter())
146    }
147
148    // /// Find the position of the pin.
149    // fn pin_position(&self, pin: &Self::PinId) -> usize {
150    //     self.for_each_pin(&self.parent_cell_of_pin(pin))
151    //         .enumerate()
152    //         .find(|(_, p)| p == pin)
153    //         .map(|(idx, _)| idx)
154    //         .expect("pin ID does not exist")
155    // }
156
157    /// Call a function for each pin instance of the circuit instance.
158    fn for_each_pin_instance<F>(&self, circuit_inst: &Self::CellInstId, f: F)
159    where
160        F: FnMut(Self::PinInstId);
161
162    /// Get a `Vec` with the IDs of all pin instance of this circuit instance.
163    fn each_pin_instance_vec(&self, circuit_instance: &Self::CellInstId) -> Vec<Self::PinInstId> {
164        let mut v = Vec::new();
165        self.for_each_pin_instance(circuit_instance, |c| v.push(c));
166        v
167    }
168
169    /// Iterate over all pin instances of a circuit.
170    fn each_pin_instance<'a>(
171        &'a self,
172        circuit_instance: &Self::CellInstId,
173    ) -> Box<dyn Iterator<Item = Self::PinInstId> + 'a> {
174        Box::new(self.each_pin_instance_vec(circuit_instance).into_iter())
175    }
176
177    /// Iterate over all external nets connected to the circuit instance.
178    /// A net might appear more than once.
179    fn each_external_net<'a>(
180        &'a self,
181        circuit_instance: &Self::CellInstId,
182    ) -> Box<dyn Iterator<Item = Self::NetId> + 'a> {
183        Box::new(
184            self.each_pin_instance(circuit_instance)
185                .flat_map(move |pin_id| self.net_of_pin_instance(&pin_id)),
186        )
187    }
188
189    /// Iterate over all external nets connected to the circuit instance.
190    /// A net might appear more than once.
191    fn for_each_external_net<F>(&self, circuit_instance: &Self::CellInstId, mut f: F)
192    where
193        F: FnMut(Self::NetId),
194    {
195        self.for_each_pin_instance(circuit_instance, |i| {
196            self.net_of_pin_instance(&i)
197                .iter()
198                .cloned()
199                .for_each(|n| f(n))
200        });
201    }
202
203    /// Get a vector of all external nets connected to the circuit instance.
204    /// A net might appear more than once.
205    fn each_external_net_vec(&self, circuit_instance: &Self::CellInstId) -> Vec<Self::NetId> {
206        let mut v = Vec::new();
207        self.for_each_external_net(circuit_instance, |n| v.push(n));
208        v
209    }
210
211    /// Call a function for net of the circuit.
212    fn for_each_internal_net<F>(&self, circuit: &Self::CellId, f: F)
213    where
214        F: FnMut(Self::NetId);
215
216    /// Get a `Vec` with all nets in this circuit.
217    fn each_internal_net_vec(&self, circuit: &Self::CellId) -> Vec<Self::NetId> {
218        let mut v = Vec::new();
219        self.for_each_internal_net(circuit, |c| v.push(c));
220        v
221    }
222
223    /// Iterate over all defined nets inside a circuit.
224    fn each_internal_net<'a>(
225        &'a self,
226        circuit: &Self::CellId,
227    ) -> Box<dyn Iterator<Item = Self::NetId> + 'a> {
228        Box::new(self.each_internal_net_vec(circuit).into_iter())
229    }
230
231    /// Return the number of nets defined inside a cell.
232    fn num_internal_nets(&self, circuit: &Self::CellId) -> usize {
233        // Inefficient default implementation.
234        let mut counter = 0;
235        self.for_each_internal_net(circuit, |_| counter += 1);
236        counter
237    }
238
239    /// Get the number of pins that are connected to this net.
240    fn num_net_pins(&self, net: &Self::NetId) -> usize {
241        let mut n = 0;
242        self.for_each_pin_of_net(net, |_| n += 1);
243        n
244    }
245
246    /// Get the number of pin instances that are connected to this net.
247    fn num_net_pin_instances(&self, net: &Self::NetId) -> usize {
248        let mut n = 0;
249        self.for_each_pin_instance_of_net(net, |_| n += 1);
250        n
251    }
252
253    /// Get the number of terminals that are connected to this net.
254    fn num_net_terminals(&self, net: &Self::NetId) -> usize {
255        self.num_net_pins(net) + self.num_net_pin_instances(net)
256    }
257
258    /// Get the number of pins of a circuit.
259    fn num_pins(&self, circuit: &Self::CellId) -> usize;
260
261    /// Call a function for each pin connected to this net.
262    fn for_each_pin_of_net<F>(&self, net: &Self::NetId, f: F)
263    where
264        F: FnMut(Self::PinId);
265
266    /// Get a `Vec` with all pin IDs connected to this net.
267    fn each_pin_of_net_vec(&self, net: &Self::NetId) -> Vec<Self::PinId> {
268        let mut v = Vec::new();
269        self.for_each_pin_of_net(net, |c| v.push(c));
270        v
271    }
272
273    /// Iterate over all pins of a net.
274    fn each_pin_of_net<'a>(
275        &'a self,
276        net: &Self::NetId,
277    ) -> Box<dyn Iterator<Item = Self::PinId> + 'a> {
278        Box::new(self.each_pin_of_net_vec(net).into_iter())
279    }
280
281    /// Call a function for each pin instance connected to this net.
282    fn for_each_pin_instance_of_net<F>(&self, net: &Self::NetId, f: F)
283    where
284        F: FnMut(Self::PinInstId);
285
286    /// Get a `Vec` with all pin instance IDs connected to this net.
287    fn each_pin_instance_of_net_vec(&self, net: &Self::NetId) -> Vec<Self::PinInstId> {
288        let mut v = Vec::new();
289        self.for_each_pin_instance_of_net(net, |c| v.push(c));
290        v
291    }
292
293    /// Iterate over all pins of a net.
294    fn each_pin_instance_of_net<'a>(
295        &'a self,
296        net: &Self::NetId,
297    ) -> Box<dyn Iterator<Item = Self::PinInstId> + 'a> {
298        Box::new(self.each_pin_instance_of_net_vec(net).into_iter())
299    }
300}
301
302/// Trait for netlists that support editing.
303///
304/// This includes:
305///
306/// * creation and removal of pins and nets
307/// * connecting pins and pin instances to nets
308/// * renaming nets
309/// * renaming pins
310///
311/// More complex operations which can be build on top of the basic operations
312/// are provided by the [`NetlistEditUtil`] trait.
313///
314/// [`NetlistEditUtil`]: crate::netlist::util::NetlistEditUtil
315#[portrait::make(import(crate::prelude::Direction))]
316pub trait NetlistEdit: NetlistBase + HierarchyEdit {
317    // /// Create a multi-bit port.
318    // /// Internally creates a pin for every bit of the port.
319    // fn create_bus(&mut self, circuit: &Self::CellId, name: Self::NameType, direction: Direction, width: usize) -> Vec<Self::PinId>;
320
321    /// Create a new pin in this cell.
322    /// Also adds the pin to all instances of the cell.
323    fn create_pin(
324        &mut self,
325        cell: &Self::CellId,
326        name: Self::NameType,
327        direction: Direction,
328    ) -> Self::PinId;
329
330    /// Remove the pin from this circuit and from all instances of this circuit.
331    fn remove_pin(&mut self, id: &Self::PinId);
332
333    /// Change the name of the pin, returns the old name.
334    /// # Panics
335    /// Panics when the name is already occupied.
336    fn rename_pin(&mut self, pin: &Self::PinId, new_name: Self::NameType) -> Self::NameType;
337
338    /// Create a net net that lives in the `parent` circuit.
339    fn create_net(&mut self, parent: &Self::CellId, name: Option<Self::NameType>) -> Self::NetId;
340
341    /// Set a new name for the net. This might panic if the name already exists.
342    /// Returns the old name.
343    fn rename_net(
344        &mut self,
345        net_id: &Self::NetId,
346        new_name: Option<Self::NameType>,
347    ) -> Option<Self::NameType>;
348
349    /// Delete the net if it exists and disconnect all connected terminals.
350    fn remove_net(&mut self, net: &Self::NetId);
351
352    /// Connect a pin to a net.
353    /// Returns the old connected net, if any.
354    fn connect_pin(&mut self, pin: &Self::PinId, net: Option<Self::NetId>) -> Option<Self::NetId>;
355
356    /// Disconnect the pin from any connected net.
357    /// Returns the old connected net, if any.
358    fn disconnect_pin(&mut self, pin: &Self::PinId) -> Option<Self::NetId> {
359        self.connect_pin(pin, None)
360    }
361
362    /// Connect a pin instance to a net.
363    /// Returns the old connected net, if any.
364    fn connect_pin_instance(
365        &mut self,
366        pin: &Self::PinInstId,
367        net: Option<Self::NetId>,
368    ) -> Option<Self::NetId>;
369
370    /// Disconnect the pin instance from any connected net.
371    /// Returns the old connected net, if any.
372    fn disconnect_pin_instance(&mut self, pin_instance: &Self::PinInstId) -> Option<Self::NetId> {
373        self.connect_pin_instance(pin_instance, None)
374    }
375}