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}