substrate/schematic/
netlist.rs

1//! Netlist export.
2
3use std::{io::Write, path::Path, sync::Arc};
4
5use scir::NetlistLibConversion;
6
7use crate::context::Context;
8
9use super::{Schematic, conv::RawLib, schema::Schema};
10
11/// A netlister that tracks how cells and instances are translated between SCIR and the output netlist format.
12pub trait ConvertibleNetlister<S: Schema + ?Sized>:
13    scir::netlist::ConvertibleNetlister<S, Error: Into<substrate::error::Error>>
14{
15    /// Writes a netlist of a Substrate block to the given output stream.
16    fn write_netlist<B: Schematic<Schema = S>, W: Write>(
17        &self,
18        ctx: &Context,
19        block: B,
20        out: &mut W,
21        opts: Self::Options<'_>,
22    ) -> substrate::error::Result<(RawLib<S>, NetlistLibConversion)> {
23        let raw_lib = ctx.export_scir(block)?;
24
25        let conv = self
26            .write_scir_netlist(&raw_lib.scir, out, opts)
27            .map_err(|e| e.into())?;
28        Ok((raw_lib, conv))
29    }
30
31    /// Writes a netlist of a Substrate block to a file at the given path.
32    ///
33    /// The file and any parent directories will be created if necessary.
34    fn write_netlist_to_file<B: Schematic<Schema = S>>(
35        &self,
36        ctx: &Context,
37        block: B,
38        path: impl AsRef<Path>,
39        opts: Self::Options<'_>,
40    ) -> substrate::error::Result<(RawLib<S>, NetlistLibConversion)> {
41        let path = path.as_ref();
42        if let Some(parent) = path.parent() {
43            std::fs::create_dir_all(parent).map_err(Arc::new)?;
44        }
45        let mut f = std::fs::File::create(path).map_err(Arc::new)?;
46        self.write_netlist(ctx, block, &mut f, opts)
47    }
48}