1#![warn(missing_docs)]
26
27use std::collections::{HashMap, HashSet, VecDeque};
28use std::fmt::{Display, Formatter};
29use std::ops::{Deref, DerefMut};
30
31use arcstr::ArcStr;
32use diagnostics::IssueSet;
33use drivers::DriverIssue;
34use indexmap::IndexMap;
35use rust_decimal::Decimal;
36use serde::{Deserialize, Serialize};
37use tracing::{Level, span};
38use uniquify::Names;
39
40use crate::schema::{FromSchema, NoSchema, NoSchemaError, Schema};
41use crate::validation::ValidatorIssue;
42pub use slice::{Concat, IndexOwned, NamedSlice, NamedSliceOne, Slice, SliceOne, SliceRange};
43
44pub mod drivers;
45pub mod merge;
46pub mod netlist;
47pub mod schema;
48mod slice;
49pub mod validation;
50
51#[cfg(test)]
52pub(crate) mod tests;
53
54#[enumify::enumify(no_as_ref, no_as_mut)]
56#[derive(Debug, Clone, Hash, PartialEq, Eq, Serialize, Deserialize)]
57pub enum ParamValue {
58 String(ArcStr),
60 Numeric(Decimal),
62}
63
64impl From<ArcStr> for ParamValue {
65 fn from(value: ArcStr) -> Self {
66 Self::String(value)
67 }
68}
69
70impl From<Decimal> for ParamValue {
71 fn from(value: Decimal) -> Self {
72 Self::Numeric(value)
73 }
74}
75
76impl Display for ParamValue {
77 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
78 match self {
79 ParamValue::String(s) => write!(f, "{}", s),
80 ParamValue::Numeric(n) => write!(f, "{}", n),
81 }
82 }
83}
84
85#[derive(
91 Copy, Clone, Debug, Default, Hash, Eq, PartialEq, Ord, PartialOrd, Serialize, Deserialize,
92)]
93pub struct SignalId(u64);
94
95impl From<Slice> for SignalId {
96 #[inline]
97 fn from(value: Slice) -> Self {
98 value.signal()
99 }
100}
101
102impl From<SliceOne> for SignalId {
103 #[inline]
104 fn from(value: SliceOne) -> Self {
105 value.signal()
106 }
107}
108
109#[derive(Clone, Debug, Hash, Eq, PartialEq, Serialize, Deserialize)]
111pub struct SlicePath(SignalPath<Slice, NamedSlice>);
112
113impl SlicePath {
114 pub fn instances(&self) -> &InstancePath {
116 &self.0.instances
117 }
118 pub fn instances_mut(&mut self) -> &mut InstancePath {
120 &mut self.0.instances
121 }
122 pub fn tail(&self) -> &SignalPathTail<Slice, NamedSlice> {
126 &self.0.tail
127 }
128}
129
130#[derive(Clone, Debug, Hash, Eq, PartialEq, Ord, PartialOrd, Serialize, Deserialize)]
132pub struct SliceOnePath(SignalPath<SliceOne, NamedSliceOne>);
133
134impl SliceOnePath {
135 pub fn new(
137 instances: InstancePath,
138 tail: impl Into<SignalPathTail<SliceOne, NamedSliceOne>>,
139 ) -> Self {
140 Self(SignalPath {
141 instances,
142 tail: tail.into(),
143 })
144 }
145 pub fn instances(&self) -> &InstancePath {
147 &self.0.instances
148 }
149 pub fn instances_mut(&mut self) -> &mut InstancePath {
151 &mut self.0.instances
152 }
153 pub fn tail(&self) -> &SignalPathTail<SliceOne, NamedSliceOne> {
157 &self.0.tail
158 }
159}
160
161#[derive(Clone, Debug, Hash, Eq, PartialEq, Ord, PartialOrd, Serialize, Deserialize)]
163struct SignalPath<I, N> {
164 instances: InstancePath,
165 tail: SignalPathTail<I, N>,
166}
167
168#[derive(Clone, Debug, Hash, Eq, PartialEq, Ord, PartialOrd, Serialize, Deserialize)]
170#[enumify::enumify(generics_only)]
171pub enum SignalPathTail<I, N> {
172 Id(I),
174 Name(N),
176}
177
178impl From<Slice> for SignalPathTail<Slice, NamedSlice> {
179 fn from(value: Slice) -> Self {
180 SignalPathTail::Id(value)
181 }
182}
183
184impl From<NamedSlice> for SignalPathTail<Slice, NamedSlice> {
185 fn from(value: NamedSlice) -> Self {
186 SignalPathTail::Name(value)
187 }
188}
189
190impl SignalPathTail<Slice, NamedSlice> {
191 pub fn range(&self) -> Option<SliceRange> {
195 match self {
196 SignalPathTail::Id(slice) => slice.range(),
197 SignalPathTail::Name(slice) => slice.range(),
198 }
199 }
200}
201
202impl From<SliceOne> for SignalPathTail<SliceOne, NamedSliceOne> {
203 fn from(value: SliceOne) -> Self {
204 SignalPathTail::Id(value)
205 }
206}
207
208impl From<NamedSliceOne> for SignalPathTail<SliceOne, NamedSliceOne> {
209 fn from(value: NamedSliceOne) -> Self {
210 SignalPathTail::Name(value)
211 }
212}
213
214impl SignalPathTail<SliceOne, NamedSliceOne> {
215 pub fn index(&self) -> Option<usize> {
217 match self {
218 SignalPathTail::Id(slice) => slice.index(),
219 SignalPathTail::Name(slice) => slice.index(),
220 }
221 }
222}
223
224#[derive(Clone, Debug, Hash, Eq, PartialEq, Ord, PartialOrd, Serialize, Deserialize)]
226pub struct InstancePath {
227 top: InstancePathCell,
229 elems: Vec<InstancePathElement>,
231}
232
233impl Deref for InstancePath {
234 type Target = Vec<InstancePathElement>;
235
236 fn deref(&self) -> &Self::Target {
237 &self.elems
238 }
239}
240
241impl DerefMut for InstancePath {
242 fn deref_mut(&mut self) -> &mut Self::Target {
243 &mut self.elems
244 }
245}
246
247impl InstancePath {
248 pub fn new(top: impl Into<InstancePathCell>) -> Self {
250 Self {
251 top: top.into(),
252 elems: Vec::new(),
253 }
254 }
255
256 pub fn push(&mut self, elem: impl Into<InstancePathElement>) {
258 self.elems.push(elem.into())
259 }
260
261 pub fn push_iter<E: Into<InstancePathElement>>(&mut self, elems: impl IntoIterator<Item = E>) {
263 for elem in elems {
264 self.push(elem);
265 }
266 }
267
268 pub fn top(&self) -> &InstancePathCell {
270 &self.top
271 }
272
273 pub fn is_empty(&self) -> bool {
275 self.elems.is_empty()
276 }
277
278 pub fn slice_one(
280 self,
281 tail: impl Into<SignalPathTail<SliceOne, NamedSliceOne>>,
282 ) -> SliceOnePath {
283 SliceOnePath(SignalPath {
284 instances: self,
285 tail: tail.into(),
286 })
287 }
288}
289
290#[derive(Clone, Debug, Hash, Eq, PartialEq, Ord, PartialOrd, Serialize, Deserialize)]
292#[enumify::enumify]
293pub enum InstancePathCell {
294 Id(CellId),
296 Name(ArcStr),
298}
299
300impl From<CellId> for InstancePathCell {
301 fn from(value: CellId) -> Self {
302 Self::Id(value)
303 }
304}
305
306impl<S: Into<ArcStr>> From<S> for InstancePathCell {
307 fn from(value: S) -> Self {
308 Self::Name(value.into())
309 }
310}
311
312#[derive(Clone, Debug, Hash, Eq, PartialEq, Ord, PartialOrd, Serialize, Deserialize)]
314#[enumify::enumify]
315pub enum InstancePathElement {
316 Id(InstanceId),
318 Name(ArcStr),
320}
321
322impl From<InstanceId> for InstancePathElement {
323 fn from(value: InstanceId) -> Self {
324 Self::Id(value)
325 }
326}
327
328impl<S: Into<ArcStr>> From<S> for InstancePathElement {
329 fn from(value: S) -> Self {
330 Self::Name(value.into())
331 }
332}
333
334#[derive(Clone, Debug, Hash, Eq, PartialEq, Ord, PartialOrd, Serialize, Deserialize)]
336pub struct AnnotatedInstancePath {
337 pub top: InstancePathCell,
341 pub instances: Vec<AnnotatedInstancePathElement>,
343}
344
345impl AnnotatedInstancePath {
346 fn bot(&self) -> Option<CellId> {
347 self.instances
348 .last()
349 .and_then(|inst| inst.child?.into_cell())
350 .or_else(|| self.top.get_id().copied())
351 }
352}
353
354#[derive(Clone, Debug, Hash, Eq, PartialEq, Ord, PartialOrd, Serialize, Deserialize)]
356pub struct AnnotatedInstancePathElement {
357 pub elem: InstancePathElement,
359 pub child: Option<ChildId>,
361}
362
363impl From<AnnotatedInstancePath> for InstancePath {
364 fn from(value: AnnotatedInstancePath) -> Self {
365 let AnnotatedInstancePath { top, instances } = value;
366
367 InstancePath {
368 top,
369 elems: instances
370 .into_iter()
371 .map(|instance| instance.elem)
372 .collect(),
373 }
374 }
375}
376
377#[derive(Clone, Default, Debug, Hash, Eq, PartialEq, Serialize, Deserialize)]
379pub struct NamedPath(Vec<ArcStr>);
380
381impl Deref for NamedPath {
382 type Target = Vec<ArcStr>;
383
384 fn deref(&self) -> &Self::Target {
385 &self.0
386 }
387}
388
389impl DerefMut for NamedPath {
390 fn deref_mut(&mut self) -> &mut Self::Target {
391 &mut self.0
392 }
393}
394
395impl NamedPath {
396 fn new() -> Self {
397 Self::default()
398 }
399
400 pub fn into_vec(self) -> Vec<ArcStr> {
402 self.0
403 }
404}
405
406#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq, Ord, PartialOrd, Serialize, Deserialize)]
412pub struct CellId(u64);
413
414#[derive(
420 Copy, Clone, Debug, Default, Hash, Eq, PartialEq, Ord, PartialOrd, Serialize, Deserialize,
421)]
422pub struct InstanceId(u64);
423
424#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq, Ord, PartialOrd, Serialize, Deserialize)]
430pub struct PrimitiveId(u64);
431
432impl Display for SignalId {
433 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
434 write!(f, "signal{}", self.0)
435 }
436}
437
438impl Display for CellId {
439 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
440 write!(f, "cell{}", self.0)
441 }
442}
443
444impl Display for InstanceId {
445 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
446 write!(f, "inst{}", self.0)
447 }
448}
449
450impl Display for PrimitiveId {
451 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
452 write!(f, "primitive{}", self.0)
453 }
454}
455
456impl Display for ChildId {
457 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
458 match self {
459 ChildId::Cell(c) => c.fmt(f),
460 ChildId::Primitive(p) => p.fmt(f),
461 }
462 }
463}
464
465pub struct LibraryBuilder<S: Schema + ?Sized = NoSchema> {
467 cell_id: u64,
472
473 primitive_id: u64,
478
479 cells: IndexMap<CellId, Cell>,
481
482 name_map: HashMap<ArcStr, CellId>,
486
487 names: Names<CellId>,
489
490 primitives: IndexMap<PrimitiveId, S::Primitive>,
492
493 top: Option<CellId>,
495}
496
497impl<S: Schema + ?Sized> Default for LibraryBuilder<S> {
498 fn default() -> Self {
499 Self {
500 cell_id: 0,
501 primitive_id: 0,
502 cells: IndexMap::new(),
503 primitives: IndexMap::new(),
504 name_map: HashMap::new(),
505 names: Names::new(),
506 top: None,
507 }
508 }
509}
510
511impl<S: Schema<Primitive = impl Clone> + ?Sized> Clone for LibraryBuilder<S> {
512 fn clone(&self) -> Self {
513 Self {
514 cell_id: self.cell_id,
515 primitive_id: self.primitive_id,
516 cells: self.cells.clone(),
517 name_map: self.name_map.clone(),
518 names: self.names.clone(),
519 primitives: self.primitives.clone(),
520 top: self.top,
521 }
522 }
523}
524
525impl<S: Schema<Primitive = impl std::fmt::Debug> + ?Sized> std::fmt::Debug for LibraryBuilder<S> {
526 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
527 let mut builder = f.debug_struct("LibraryBuilder");
528 let _ = builder.field("cell_id", &self.cell_id);
529 let _ = builder.field("primitive_id", &self.primitive_id);
530 let _ = builder.field("cells", &self.cells);
531 let _ = builder.field("name_map", &self.name_map);
532 let _ = builder.field("names", &self.names);
533 let _ = builder.field("primitives", &self.primitives);
534 let _ = builder.field("top", &self.top);
535 builder.finish()
536 }
537}
538
539pub struct Library<S: Schema + ?Sized = NoSchema>(LibraryBuilder<S>);
544
545impl<S: Schema<Primitive = impl std::fmt::Debug> + ?Sized> std::fmt::Debug for Library<S> {
546 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
547 let mut builder = f.debug_struct("Library");
548 let _ = builder.field("0", &self.0);
549 builder.finish()
550 }
551}
552
553impl<S: Schema + ?Sized> Clone for Library<S>
554where
555 LibraryBuilder<S>: Clone,
556{
557 fn clone(&self) -> Self {
558 Self(self.0.clone())
559 }
560}
561
562impl<S: Schema + ?Sized> Deref for Library<S> {
563 type Target = LibraryBuilder<S>;
564 fn deref(&self) -> &Self::Target {
565 &self.0
566 }
567}
568
569impl<S: Schema + ?Sized> Library<S> {
570 pub fn drop_schema(self) -> Result<Library<NoSchema>, NoSchemaError> {
573 Ok(Library(self.0.drop_schema()?))
574 }
575
576 pub fn convert_schema<C>(self) -> Result<LibraryBuilder<C>, C::Error>
581 where
582 C: FromSchema<S> + ?Sized,
583 {
584 self.0.convert_schema()
585 }
586
587 pub fn into_builder(self) -> LibraryBuilder<S> {
589 self.0
590 }
591}
592
593impl<S: Schema<Primitive = impl Clone> + ?Sized> Library<S> {
594 pub fn from_cell_named(lib: &Self, cell: &str) -> Self {
597 LibraryBuilder::from_cell_named(lib, cell).build().unwrap()
598 }
599}
600
601#[derive(Debug, Clone)]
603pub struct Issues {
604 pub correctness: IssueSet<ValidatorIssue>,
606 pub drivers: IssueSet<DriverIssue>,
608}
609
610impl Display for Issues {
611 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
612 if self.correctness.is_empty() && self.drivers.is_empty() {
613 write!(f, "no issues")?;
614 }
615 if !self.correctness.is_empty() {
616 writeln!(f, "correctness issues:\n{}", self.correctness)?;
617 }
618 if !self.drivers.is_empty() {
619 writeln!(f, "driver issues:\n{}", self.drivers)?;
620 }
621 Ok(())
622 }
623}
624
625impl std::error::Error for Issues {}
626
627impl Issues {
628 pub fn has_warning(&self) -> bool {
630 self.correctness.has_warning() || self.drivers.has_warning()
631 }
632
633 pub fn has_error(&self) -> bool {
635 self.correctness.has_error() || self.drivers.has_error()
636 }
637}
638
639#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Default, Serialize, Deserialize)]
641pub enum Direction {
642 Input,
644 Output,
646 #[default]
651 InOut,
652}
653
654impl Direction {
655 #[inline]
668 pub fn flip(&self) -> Self {
669 match *self {
670 Self::Input => Self::Output,
671 Self::Output => Self::Input,
672 Self::InOut => Self::InOut,
673 }
674 }
675
676 pub fn is_compatible_with(&self, other: Direction) -> bool {
688 use Direction::*;
689
690 #[allow(clippy::match_like_matches_macro)]
691 match (*self, other) {
692 (Output, Output) => false,
693 _ => true,
694 }
695 }
696}
697
698impl Display for Direction {
699 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
700 match *self {
701 Self::Output => write!(f, "output"),
702 Self::Input => write!(f, "input"),
703 Self::InOut => write!(f, "inout"),
704 }
705 }
706}
707
708#[derive(Debug, Clone, Serialize, Deserialize)]
710pub struct Port {
711 signal: SignalId,
712 direction: Direction,
713}
714
715#[derive(Debug, Clone, Serialize, Deserialize)]
717pub struct SignalInfo {
718 pub id: SignalId,
720
721 pub name: ArcStr,
723
724 pub width: Option<usize>,
728
729 pub port: Option<usize>,
734}
735
736impl SignalInfo {
737 #[inline]
739 pub fn slice(&self) -> Slice {
740 Slice::new(self.id, self.width.map(SliceRange::with_width))
741 }
742
743 pub fn is_port(&self) -> bool {
745 self.port.is_some()
746 }
747}
748
749#[derive(Debug, Clone, Serialize, Deserialize)]
751pub struct Instance {
752 child: ChildId,
754 name: ArcStr,
758 connections: HashMap<ArcStr, Concat>,
763}
764
765#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq, Ord, PartialOrd, Serialize, Deserialize)]
767#[enumify::enumify(no_as_ref, no_as_mut)]
768pub enum ChildId {
769 Cell(CellId),
771 Primitive(PrimitiveId),
775}
776
777impl From<CellId> for ChildId {
778 fn from(value: CellId) -> Self {
779 Self::Cell(value)
780 }
781}
782
783impl From<PrimitiveId> for ChildId {
784 fn from(value: PrimitiveId) -> Self {
785 Self::Primitive(value)
786 }
787}
788
789#[derive(Debug, Clone, Serialize, Deserialize)]
791pub struct Cell {
792 signal_id: u64,
796 port_idx: usize,
797 pub(crate) name: ArcStr,
798 pub(crate) ports: IndexMap<ArcStr, Port>,
799 pub(crate) signals: HashMap<SignalId, SignalInfo>,
800 signal_name_map: HashMap<ArcStr, SignalId>,
804 instance_id: u64,
808 pub(crate) instances: IndexMap<InstanceId, Instance>,
809 instance_name_map: HashMap<ArcStr, InstanceId>,
813}
814
815#[derive(Debug, Clone, Default)]
817pub struct NetlistLibConversion {
818 pub cells: HashMap<CellId, NetlistCellConversion>,
820}
821
822impl NetlistLibConversion {
823 pub fn new() -> Self {
825 Self::default()
826 }
827}
828
829#[derive(Debug, Clone, Default)]
831pub struct NetlistCellConversion {
832 pub instances: HashMap<InstanceId, ArcStr>,
834}
835
836impl NetlistCellConversion {
837 pub fn new() -> Self {
839 Self::default()
840 }
841}
842
843impl<S: Schema + ?Sized> LibraryBuilder<S> {
844 pub fn new() -> Self {
846 Self::default()
847 }
848
849 pub fn add_cell(&mut self, cell: Cell) -> CellId {
853 let id = self.alloc_cell_id();
854 self.name_map.insert(cell.name.clone(), id);
855 self.names.reserve_name(id, cell.name.clone());
856 self.cells.insert(id, cell);
857 id
858 }
859
860 pub fn merge_cell(&mut self, mut cell: Cell) -> CellId {
864 let id = self.alloc_cell_id();
865 let n_name = self.names.assign_name(id, &cell.name);
866 cell.name = n_name;
867 self.name_map.insert(cell.name.clone(), id);
868 self.cells.insert(id, cell);
869 id
870 }
871
872 #[inline]
873 pub(crate) fn alloc_cell_id(&mut self) -> CellId {
874 self.cell_id += 1;
875 self.curr_cell_id()
876 }
877
878 #[inline]
879 pub(crate) fn curr_cell_id(&self) -> CellId {
880 CellId(self.cell_id)
881 }
882
883 pub(crate) fn add_cell_with_id(&mut self, id: impl Into<CellId>, cell: Cell) {
891 let id = id.into();
892 assert!(!self.cells.contains_key(&id));
893 self.cell_id = std::cmp::max(id.0, self.cell_id);
894 self.name_map.insert(cell.name.clone(), id);
895 self.names.reserve_name(id, cell.name.clone());
896 self.cells.insert(id, cell);
897 }
898
899 #[doc(hidden)]
909 pub fn overwrite_cell_with_id(&mut self, id: impl Into<CellId>, cell: Cell) {
910 let id = id.into();
911 assert!(self.cells.contains_key(&id));
912 self.cell_id = std::cmp::max(id.0, self.cell_id);
913 self.name_map.insert(cell.name.clone(), id);
914 self.cells.insert(id, cell);
915 }
916
917 pub fn add_primitive(&mut self, primitive: S::Primitive) -> PrimitiveId {
921 let id = self.alloc_primitive_id();
922 self.primitives.insert(id, primitive);
923 id
924 }
925
926 #[inline]
927 pub(crate) fn alloc_primitive_id(&mut self) -> PrimitiveId {
928 self.primitive_id += 1;
929 self.curr_primitive_id()
930 }
931
932 #[inline]
933 pub(crate) fn curr_primitive_id(&self) -> PrimitiveId {
934 PrimitiveId(self.primitive_id)
935 }
936
937 pub(crate) fn add_primitive_with_id(
945 &mut self,
946 id: impl Into<PrimitiveId>,
947 primitive: S::Primitive,
948 ) {
949 let id = id.into();
950 assert!(!self.primitives.contains_key(&id));
951 self.primitive_id = std::cmp::max(id.0, self.primitive_id);
952 self.primitives.insert(id, primitive);
953 }
954
955 #[doc(hidden)]
965 pub fn overwrite_primitive_with_id(
966 &mut self,
967 id: impl Into<PrimitiveId>,
968 primitive: S::Primitive,
969 ) {
970 let id = id.into();
971 assert!(self.primitives.contains_key(&id));
972 self.primitive_id = std::cmp::max(id.0, self.primitive_id);
973 self.primitives.insert(id, primitive);
974 }
975
976 pub fn set_top(&mut self, cell: CellId) {
978 self.top = Some(cell);
979 }
980
981 #[inline]
983 pub fn top_cell(&self) -> Option<CellId> {
984 self.top
985 }
986
987 pub fn is_top(&self, cell: CellId) -> bool {
989 self.top_cell().map(|c| c == cell).unwrap_or_default()
990 }
991
992 pub fn cell(&self, id: CellId) -> &Cell {
999 self.cells.get(&id).unwrap()
1000 }
1001
1002 #[inline]
1004 pub fn try_cell(&self, id: CellId) -> Option<&Cell> {
1005 self.cells.get(&id)
1006 }
1007
1008 pub fn cell_named(&self, name: &str) -> &Cell {
1014 self.cell(*self.name_map.get(name).unwrap())
1015 }
1016
1017 pub fn try_cell_named(&self, name: &str) -> Option<&Cell> {
1019 self.try_cell(*self.name_map.get(name)?)
1020 }
1021
1022 pub fn cell_id_named(&self, name: &str) -> CellId {
1029 match self.name_map.get(name) {
1030 Some(&cell) => cell,
1031 None => {
1032 tracing::error!("no cell named `{}`", name);
1033 panic!("no cell named `{}`", name);
1034 }
1035 }
1036 }
1037
1038 pub fn try_cell_id_named(&self, name: &str) -> Option<CellId> {
1040 self.name_map.get(name).copied()
1041 }
1042
1043 pub fn cells(&self) -> impl Iterator<Item = (CellId, &Cell)> {
1045 self.cells.iter().map(|(id, cell)| (*id, cell))
1046 }
1047
1048 pub fn retain_cells(&mut self, roots: impl IntoIterator<Item = CellId>) {
1050 let (cells, primitives) = self.cells_and_primitives_used_by(roots);
1051 self.name_map.retain(|_, cell| cells.contains(cell));
1053 for (id, _) in self.cells.iter() {
1054 if !cells.contains(id) {
1055 self.names.unassign(id);
1057 }
1058 }
1059 self.cells.retain(|id, _| cells.contains(id));
1061
1062 if let Some(top) = self.top_cell()
1064 && !cells.contains(&top)
1065 {
1066 self.top = None;
1067 }
1068
1069 self.primitives.retain(|id, _| primitives.contains(id));
1071 }
1072
1073 pub(crate) fn cells_and_primitives_used_by(
1077 &self,
1078 roots: impl IntoIterator<Item = CellId>,
1079 ) -> (HashSet<CellId>, HashSet<PrimitiveId>) {
1080 let mut stack = VecDeque::new();
1081 let mut visited = HashSet::new();
1082 let mut primitives = HashSet::new();
1083 for root in roots {
1084 stack.push_back(root);
1085 }
1086
1087 while let Some(id) = stack.pop_front() {
1088 if visited.contains(&id) {
1089 continue;
1090 }
1091 visited.insert(id);
1092 let cell = self.cell(id);
1093 for (_, inst) in cell.instances() {
1094 match inst.child {
1095 ChildId::Cell(c) => {
1096 stack.push_back(c);
1097 }
1098 ChildId::Primitive(p) => {
1099 primitives.insert(p);
1100 }
1101 }
1102 }
1103 }
1104
1105 (visited, primitives)
1106 }
1107
1108 pub(crate) fn cells_used_by(&self, roots: impl IntoIterator<Item = CellId>) -> HashSet<CellId> {
1112 let mut stack = VecDeque::new();
1113 let mut visited = HashSet::new();
1114 for root in roots {
1115 stack.push_back(root);
1116 }
1117
1118 while let Some(id) = stack.pop_front() {
1119 if visited.contains(&id) {
1120 continue;
1121 }
1122 visited.insert(id);
1123 let cell = self.cell(id);
1124 for (_, inst) in cell.instances() {
1125 if let ChildId::Cell(c) = inst.child {
1126 stack.push_back(c);
1127 }
1128 }
1129 }
1130
1131 visited
1132 }
1133
1134 pub fn primitive(&self, id: PrimitiveId) -> &S::Primitive {
1141 self.primitives.get(&id).unwrap()
1142 }
1143
1144 #[inline]
1146 pub fn try_primitive(&self, id: PrimitiveId) -> Option<&S::Primitive> {
1147 self.primitives.get(&id)
1148 }
1149
1150 pub fn primitives(&self) -> impl Iterator<Item = (PrimitiveId, &S::Primitive)> {
1152 self.primitives
1153 .iter()
1154 .map(|(id, primitive)| (*id, primitive))
1155 }
1156
1157 fn convert_instance_path_cell(&self, top: &InstancePathCell) -> Option<(CellId, &Cell)> {
1158 Some(match top {
1159 InstancePathCell::Id(id) => (*id, self.cell(*id)),
1160 InstancePathCell::Name(name) => (
1161 *self.name_map.get(name)?,
1162 self.try_cell_named(name.as_ref())?,
1163 ),
1164 })
1165 }
1166
1167 pub fn annotate_instance_path(&self, path: InstancePath) -> AnnotatedInstancePath {
1172 let mut annotated_elems = Vec::new();
1173
1174 let (top, mut cell) = if let Some((id, cell)) = self.convert_instance_path_cell(&path.top) {
1175 (Some(id), Some(cell))
1176 } else {
1177 (None, None)
1178 };
1179
1180 for instance in path.elems {
1181 if let Some(cell_inner) = cell {
1182 let child = match &instance {
1183 InstancePathElement::Id(id) => cell_inner.try_instance(*id),
1184 InstancePathElement::Name(name) => cell_inner.try_instance_named(name),
1185 }
1186 .map(|inst| inst.child);
1187
1188 annotated_elems.push(AnnotatedInstancePathElement {
1189 elem: instance,
1190 child,
1191 });
1192
1193 cell = match child {
1194 Some(ChildId::Cell(c)) => self.try_cell(c),
1195 _ => None,
1196 };
1197 } else {
1198 annotated_elems.push(AnnotatedInstancePathElement {
1199 elem: instance.clone(),
1200 child: None,
1201 });
1202 }
1203 }
1204
1205 AnnotatedInstancePath {
1206 top: top.map(|top| top.into()).unwrap_or(path.top),
1207 instances: annotated_elems,
1208 }
1209 }
1210
1211 pub fn convert_annotated_instance_path(
1214 &self,
1215 conv: Option<&NetlistLibConversion>,
1216 path: AnnotatedInstancePath,
1217 ) -> NamedPath {
1218 let mut named_path = NamedPath::new();
1219
1220 let (top_id, top) = if let Some((top_id, top)) = self.convert_instance_path_cell(&path.top)
1221 {
1222 (Some(top_id), Some(top))
1223 } else {
1224 (None, None)
1225 };
1226
1227 for (i, instance) in path.instances.iter().enumerate() {
1228 match &instance.elem {
1229 InstancePathElement::Id(id) => {
1230 let inst = if i == 0 {
1231 top
1232 } else {
1233 self.try_cell(path.instances[i - 1].child.unwrap().unwrap_cell())
1234 }
1235 .unwrap()
1236 .instance(*id);
1237
1238 let name = conv
1239 .and_then(|conv| {
1240 Some(
1241 conv.cells
1242 .get(&if i == 0 {
1243 top_id?
1244 } else {
1245 path.instances[i - 1].child.unwrap().unwrap_cell()
1246 })?
1247 .instances
1248 .get(id)?
1249 .clone(),
1250 )
1251 })
1252 .unwrap_or(inst.name().clone());
1253 named_path.push(name);
1254 }
1255 InstancePathElement::Name(name) => {
1256 named_path.push(name.clone());
1257 }
1258 }
1259 }
1260
1261 named_path
1262 }
1263
1264 pub fn convert_instance_path(&self, path: InstancePath) -> NamedPath {
1270 let annotated_path = self.annotate_instance_path(path);
1271
1272 self.convert_annotated_instance_path(None, annotated_path)
1273 }
1274
1275 pub fn convert_instance_path_with_conv(
1282 &self,
1283 conv: &NetlistLibConversion,
1284 path: InstancePath,
1285 ) -> NamedPath {
1286 let annotated_path = self.annotate_instance_path(path);
1287
1288 self.convert_annotated_instance_path(Some(conv), annotated_path)
1289 }
1290
1291 fn convert_slice_one_path_inner(
1298 &self,
1299 conv: Option<&NetlistLibConversion>,
1300 path: SliceOnePath,
1301 index_fmt: impl FnOnce(&ArcStr, Option<usize>) -> ArcStr,
1302 ) -> NamedPath {
1303 let SignalPath { instances, tail } = path.0;
1304 let annotated_path = self.annotate_instance_path(instances);
1305
1306 let bot = self.cell(annotated_path.bot().unwrap());
1307
1308 let (name, index) = match &tail {
1309 SignalPathTail::Id(id) => (&bot.signal(id.signal()).name, id.index()),
1310 SignalPathTail::Name(name) => (name.signal(), name.index()),
1311 };
1312
1313 let mut name_path = self.convert_annotated_instance_path(conv, annotated_path);
1314 name_path.push(index_fmt(name, index));
1315
1316 name_path
1317 }
1318
1319 pub fn convert_slice_one_path(
1326 &self,
1327 path: SliceOnePath,
1328 index_fmt: impl FnOnce(&ArcStr, Option<usize>) -> ArcStr,
1329 ) -> NamedPath {
1330 self.convert_slice_one_path_inner(None, path, index_fmt)
1331 }
1332
1333 pub fn convert_slice_one_path_with_conv(
1340 &self,
1341 conv: &NetlistLibConversion,
1342 path: SliceOnePath,
1343 index_fmt: impl FnOnce(&ArcStr, Option<usize>) -> ArcStr,
1344 ) -> NamedPath {
1345 self.convert_slice_one_path_inner(Some(conv), path, index_fmt)
1346 }
1347
1348 pub fn simplify_path(&self, path: SliceOnePath) -> SliceOnePath {
1354 if path.instances().is_empty() {
1355 return path;
1356 }
1357 let SignalPath {
1358 instances,
1359 mut tail,
1360 } = path.0;
1361
1362 let mut annotated_instances = self.annotate_instance_path(instances);
1363 let top = self
1364 .convert_instance_path_cell(&annotated_instances.top)
1365 .map(|(_, cell)| cell);
1366
1367 for i in (0..annotated_instances.instances.len()).rev() {
1368 let parent = if i == 0 {
1369 top.unwrap()
1370 } else {
1371 self.cell(
1372 annotated_instances.instances[i - 1]
1373 .child
1374 .unwrap()
1375 .unwrap_cell(),
1376 )
1377 };
1378 match annotated_instances.instances[i].child.unwrap() {
1379 ChildId::Cell(id) => {
1380 let cell = self.cell(id);
1381 let info = match &tail {
1382 SignalPathTail::Id(id) => cell.signal(id.signal()),
1383 SignalPathTail::Name(name) => cell.signal_named(name.signal()),
1384 };
1385 if info.port.is_none() {
1386 annotated_instances.instances.truncate(i + 1);
1387 return SliceOnePath(SignalPath {
1388 instances: annotated_instances.into(),
1389 tail,
1390 });
1391 } else {
1392 let inst = parent
1393 .instance_from_path_element(&annotated_instances.instances[i].elem);
1394 let idx = tail.index().unwrap_or_default();
1395 tail = SignalPathTail::Id(inst.connection(info.name.as_ref()).index(idx));
1396 }
1397 }
1398 ChildId::Primitive(_) => {
1399 let inst =
1400 parent.instance_from_path_element(&annotated_instances.instances[i].elem);
1401 tail = SignalPathTail::Id(match &tail {
1402 SignalPathTail::Id(_) => {
1403 panic!("only paths to named primitive ports can be simplified")
1404 }
1405 SignalPathTail::Name(name) => inst
1406 .connection(name.signal())
1407 .index(name.index().unwrap_or_default()),
1408 });
1409 }
1410 }
1411 }
1412
1413 annotated_instances.instances = Vec::new();
1414 SliceOnePath(SignalPath {
1415 instances: annotated_instances.into(),
1416 tail,
1417 })
1418 }
1419
1420 #[inline]
1430 pub fn build(self) -> Result<Library<S>, Issues> {
1431 self.try_build().map(|ok| ok.0)
1432 }
1433
1434 pub fn try_build(self) -> Result<(Library<S>, Issues), Issues> {
1446 let correctness = self.validate();
1447 let drivers = self.validate_drivers();
1448 let issues = Issues {
1449 correctness,
1450 drivers,
1451 };
1452 if issues.has_error() {
1453 Err(issues)
1454 } else {
1455 Ok((Library(self), issues))
1456 }
1457 }
1458
1459 fn convert_inner<C: Schema + ?Sized, E>(
1460 self,
1461 convert_primitive: fn(<S as Schema>::Primitive) -> Result<<C as Schema>::Primitive, E>,
1462 convert_instance: fn(&mut Instance, &<S as Schema>::Primitive) -> Result<(), E>,
1463 ) -> Result<LibraryBuilder<C>, E> {
1464 let LibraryBuilder {
1465 cell_id,
1466 primitive_id,
1467 mut cells,
1468 name_map,
1469 primitives,
1470 top,
1471 names,
1472 } = self;
1473
1474 for (_, cell) in cells.iter_mut() {
1475 for (_, instance) in cell.instances.iter_mut() {
1476 if let ChildId::Primitive(p) = instance.child
1477 && let Some(primitive) = primitives.get(&p)
1478 {
1479 convert_instance(instance, primitive)?;
1480 }
1481 }
1482 }
1483
1484 Ok(LibraryBuilder {
1485 cell_id,
1486 primitive_id,
1487 cells,
1488 name_map,
1489 names,
1490 primitives: primitives
1491 .into_iter()
1492 .map(|(k, v)| Ok((k, convert_primitive(v)?)))
1493 .collect::<Result<_, _>>()?,
1494 top,
1495 })
1496 }
1497
1498 pub fn drop_schema(self) -> Result<LibraryBuilder<NoSchema>, NoSchemaError> {
1501 self.convert_inner(|_| Err(NoSchemaError), |_, _| Err(NoSchemaError))
1502 }
1503
1504 pub fn convert_schema<C>(self) -> Result<LibraryBuilder<C>, C::Error>
1508 where
1509 C: FromSchema<S> + ?Sized,
1510 {
1511 self.convert_inner(C::convert_primitive, C::convert_instance)
1512 }
1513}
1514
1515impl<S: Schema<Primitive = impl Clone> + ?Sized> LibraryBuilder<S> {
1516 pub fn from_cell_named(lib: &Self, cell: &str) -> Self {
1519 let mut new_lib = LibraryBuilder::new();
1520 let mut cells = vec![(lib.cell_id_named(cell), lib.cell_named(cell))];
1521 while let Some((id, cell)) = cells.pop() {
1522 for (_, inst) in cell.instances() {
1523 match inst.child {
1524 ChildId::Primitive(id) => {
1525 let prim = lib.primitive(id);
1526 new_lib.add_primitive_with_id(id, prim.clone());
1527 }
1528 ChildId::Cell(cell) => {
1529 cells.push((cell, lib.cell(cell)));
1530 }
1531 }
1532 }
1533 new_lib.add_cell_with_id(id, cell.clone());
1534 }
1535 new_lib
1536 }
1537}
1538
1539impl Cell {
1540 pub fn new(name: impl Into<ArcStr>) -> Self {
1542 Self {
1543 signal_id: 0,
1544 port_idx: 0,
1545 name: name.into(),
1546 ports: IndexMap::new(),
1547 signals: HashMap::new(),
1548 signal_name_map: HashMap::new(),
1549 instance_id: 0,
1550 instances: IndexMap::new(),
1551 instance_name_map: HashMap::new(),
1552 }
1553 }
1554
1555 fn add_signal(&mut self, name: ArcStr, width: Option<usize>) -> SignalId {
1556 self.signal_id += 1;
1557 let id = SignalId(self.signal_id);
1558 self.signal_name_map.insert(name.clone(), id);
1559 self.signals.insert(
1560 id,
1561 SignalInfo {
1562 id,
1563 port: None,
1564 name,
1565 width,
1566 },
1567 );
1568 id
1569 }
1570
1571 pub fn add_node(&mut self, name: impl Into<ArcStr>) -> SliceOne {
1573 let id = self.add_signal(name.into(), None);
1574 SliceOne::new(id, None)
1575 }
1576
1577 pub fn add_bus(&mut self, name: impl Into<ArcStr>, width: usize) -> Slice {
1579 assert!(width > 0);
1580 let id = self.add_signal(name.into(), Some(width));
1581 Slice::new(id, Some(SliceRange::with_width(width)))
1582 }
1583
1584 pub fn expose_port(&mut self, signal: impl Into<SignalId>, direction: Direction) {
1594 let signal = signal.into();
1595 let info = self.signals.get_mut(&signal).unwrap();
1596
1597 if info.port.is_none() {
1599 info.port = Some(self.port_idx);
1600 self.port_idx += info.width.unwrap_or(1);
1601 self.ports
1602 .insert(info.name.clone(), Port { signal, direction });
1603 }
1604 }
1605
1606 #[inline]
1608 pub fn name(&self) -> &ArcStr {
1609 &self.name
1610 }
1611
1612 #[inline]
1614 pub fn ports(&self) -> impl Iterator<Item = &Port> {
1615 self.ports.iter().map(|(_, port)| port)
1616 }
1617
1618 #[inline]
1624 pub fn port(&self, name: &str) -> &Port {
1625 self.ports.get(name).unwrap()
1626 }
1627
1628 #[inline]
1630 pub fn signals(&self) -> impl Iterator<Item = (SignalId, &SignalInfo)> {
1631 self.signals.iter().map(|x| (*x.0, x.1))
1632 }
1633
1634 #[inline]
1640 pub fn signal(&self, id: SignalId) -> &SignalInfo {
1641 self.signals.get(&id).unwrap()
1642 }
1643
1644 #[inline]
1646 pub fn try_signal(&self, id: SignalId) -> Option<&SignalInfo> {
1647 self.signals.get(&id)
1648 }
1649
1650 #[inline]
1656 pub fn signal_named(&self, name: &str) -> &SignalInfo {
1657 self.signal(*self.signal_name_map.get(name).unwrap())
1658 }
1659
1660 #[inline]
1662 pub fn try_signal_named(&self, name: &str) -> Option<&SignalInfo> {
1663 self.try_signal(*self.signal_name_map.get(name)?)
1664 }
1665
1666 #[inline]
1672 pub fn instance(&self, id: InstanceId) -> &Instance {
1673 self.instances.get(&id).unwrap()
1674 }
1675
1676 #[inline]
1678 pub fn try_instance(&self, id: InstanceId) -> Option<&Instance> {
1679 self.instances.get(&id)
1680 }
1681
1682 pub fn instance_named(&self, name: &str) -> &Instance {
1688 self.instance(*self.instance_name_map.get(name).unwrap())
1689 }
1690
1691 pub fn try_instance_named(&self, name: &str) -> Option<&Instance> {
1693 self.try_instance(*self.instance_name_map.get(name)?)
1694 }
1695
1696 pub fn instance_from_path_element(&self, elem: &InstancePathElement) -> &Instance {
1698 match elem {
1699 InstancePathElement::Id(id) => self.instance(*id),
1700 InstancePathElement::Name(name) => self.instance_named(name),
1701 }
1702 }
1703
1704 #[inline]
1706 pub fn add_instance(&mut self, instance: Instance) -> InstanceId {
1707 self.instance_id += 1;
1708 let id = InstanceId(self.instance_id);
1709 self.instance_name_map.insert(instance.name.clone(), id);
1710 self.instances.insert(id, instance);
1711 id
1712 }
1713
1714 #[inline]
1716 pub fn instances(&self) -> impl Iterator<Item = (InstanceId, &Instance)> {
1717 self.instances.iter().map(|x| (*x.0, x.1))
1718 }
1719}
1720
1721impl Instance {
1722 pub fn new(name: impl Into<ArcStr>, child: impl Into<ChildId>) -> Self {
1724 Self {
1725 child: child.into(),
1726 name: name.into(),
1727 connections: HashMap::new(),
1728 }
1729 }
1730
1731 #[inline]
1733 pub fn connect(&mut self, name: impl Into<ArcStr>, conn: impl Into<Concat>) {
1734 self.connections.insert(name.into(), conn.into());
1735 }
1736
1737 #[inline]
1741 pub fn child(&self) -> ChildId {
1742 self.child
1743 }
1744
1745 #[inline]
1749 pub fn name(&self) -> &ArcStr {
1750 &self.name
1751 }
1752
1753 #[inline]
1755 pub fn connections(&self) -> &HashMap<ArcStr, Concat> {
1756 &self.connections
1757 }
1758
1759 #[inline]
1761 pub fn connections_mut(&mut self) -> &mut HashMap<ArcStr, Concat> {
1762 &mut self.connections
1763 }
1764
1765 #[inline]
1771 pub fn connection<'a>(&'a self, port: &str) -> &'a Concat {
1772 &self.connections[port]
1773 }
1774
1775 pub fn map_connections(&mut self, map_fn: impl Fn(ArcStr) -> ArcStr) {
1779 self.connections = self
1780 .connections
1781 .drain()
1782 .map(|(k, v)| (map_fn(k), v))
1783 .collect();
1784 }
1785}
1786
1787impl Port {
1788 #[inline]
1790 pub fn signal(&self) -> SignalId {
1791 self.signal
1792 }
1793
1794 #[inline]
1796 pub fn direction(&self) -> Direction {
1797 self.direction
1798 }
1799}