From 86c9fb4c68cb785c58d8b8b4109142730fcbe8e7 Mon Sep 17 00:00:00 2001 From: hakki Date: Wed, 25 Sep 2024 17:06:23 +0200 Subject: [PATCH] SpecctraDocs: implemented mesadata docs --- examples/specctra.rs | 2 ++ src/specctra/design.rs | 48 +++++++++++++++++++++++----------------- src/specctra/mesadata.rs | 38 +++++++++++++++++++++++++++++++ 3 files changed, 68 insertions(+), 20 deletions(-) diff --git a/examples/specctra.rs b/examples/specctra.rs index fc93b79..882526b 100644 --- a/examples/specctra.rs +++ b/examples/specctra.rs @@ -18,5 +18,7 @@ fn main() -> Result<(), std::io::Error> { let mut file = File::create("example.ses").unwrap(); design.write_ses(invoker.autorouter().board(), &mut file); + + let filename = design.get_name(); Ok(()) } diff --git a/src/specctra/design.rs b/src/specctra/design.rs index 0cbe2dc..e7fbec8 100644 --- a/src/specctra/design.rs +++ b/src/specctra/design.rs @@ -25,33 +25,34 @@ use crate::{ #[derive(Error, Debug)] -/// Possible errors raised by [`SpecctraDesign::load`] +/// Errors raised by [`SpecctraDesign::load`] pub enum LoadingError { /// I/O file reading error from [`std::io::Error`] #[error(transparent)] Io(#[from] std::io::Error), /// File parsing errors containing information about unexpected end of file, - /// or any other parsing issues with your DSN file + /// or any other parsing issues with provided DSN file #[error(transparent)] Parse(#[from] read::ParseError), } /// This struct is responsible for managing the various Specctra components of a PCB design, -/// including parsing the DSN file, handling the resolution and unit of measurement, +/// including parsing the DSN file, handling the resolution, unit of measurement, /// and organizing the PCB's structure, placement, library, network, and wiring. -/// It provides functionality for reading from a DSN file and writing session files. +/// It provides functionality for reading from a DSN file and writing Specctra's .SES session files. #[derive(Debug)] pub struct SpecctraDesign { pcb: Pcb, } impl SpecctraDesign { - /// Reads a Specctra DSN file and initializes a [`SpecctraDesign`] instance. - /// - /// # Errors + /// Loads a [`SpecctraDesign`] structure instance from a buffered reader. + /// + /// This function reads the Specctra Design data from an input stream. + /// Later the data is parsed and loaded into a [`SpecctraDesign`] structure, + /// allowing further operations such as rule validation, routing, or netlist management. /// - /// Returns a [`LoadingError`] if an I/O error occurs or if the file format is invalid. pub fn load(reader: impl std::io::BufRead) -> Result { let mut list_reader = ListTokenizer::new(reader); let dsn = list_reader.read_value::()?; @@ -59,20 +60,23 @@ impl SpecctraDesign { Ok(Self { pcb: dsn.pcb }) } - /// Retrieves the name of the PCB design and return name of the PCB as a string slice. + /// Function to get name of the DSN file + /// + /// This function returns the name of the `Pcb` objects pub fn get_name(&self) -> &str { &self.pcb.name } - /// This method generates an SES file based on the board layout and writes it to the specified writer. - /// - /// # Errors + /// Writes the Specctra Session (.ses) file format using the current board layout and mesadata. /// - /// Returns an [`std::io::Error`] if an I/O error occurs while writing the SES file. - pub fn write_ses( + /// This function generates a Specctra SES session file that represents the board's net routing and + /// writes it to the provided output stream. The session data includes routed nets, wires, + /// layers, and other essential information for routing management. + /// + pub fn write_ses( &self, board: &Board, - writer: impl std::io::Write, + writer: impl std::io::Write, ) -> Result<(), std::io::Error> { let mesadata = board.mesadata(); let drawing = board.layout().drawing(); @@ -145,8 +149,8 @@ impl SpecctraDesign { structure::NetOut { name: mesadata.net_netname(net).unwrap().to_owned(), wire: vec![wire], - via: Vec::new(), - }, + via: Vec::new() + }, ); } } @@ -173,10 +177,14 @@ impl SpecctraDesign { ListWriter::new(writer).write_value(&ses) } - - /// This method interprets the PCB design and generates a [`Board`] object - /// containing the layout and associated Specctra mesadata . + /// Generates a [`Board`] from the current PCB data. + /// + /// This function takes the internal `Pcb` structure and transforms it into a [`Board`] object, + /// which is used for layout and routing operations. The board is initialized with [`SpecctraMesadata`], + /// which includes layer and net mappings, and is populated with components, pins, vias, and wires + /// from the PCB definition. + /// pub fn make_board(&self) -> Board { let mesadata = SpecctraMesadata::from_pcb(&self.pcb); let mut board = Board::new(Layout::new(Drawing::new( diff --git a/src/specctra/mesadata.rs b/src/specctra/mesadata.rs index c53c35e..9c422ca 100644 --- a/src/specctra/mesadata.rs +++ b/src/specctra/mesadata.rs @@ -9,8 +9,18 @@ use crate::{ }; #[derive(Debug)] +/// [`SpecctraRule`] represents the basic routing constraints used by an auto-router, such as +/// the Specctra auto-router, in a PCB design process. This struct defines two key design +/// rules: the width of the trace and the minimum clearance between electrical features. pub struct SpecctraRule { + /// Specifies the width of the trace (or conductor) in millimeters. + /// This value ensures that the traces meet electrical + /// and mechanical requirements, such as current-carrying capacity or signal integrity. pub width: f64, + /// Defines the minimum clearance (spacing) between traces, pads, + /// or other conductive features on the PCB. Adequate clearance is important for + /// preventing electrical shorts or interference between signals, and is often + /// dictated by manufacturing constraints or voltage considerations. pub clearance: f64, } @@ -24,22 +34,43 @@ impl SpecctraRule { } #[derive(Debug)] +/// [`SpecctraMesadata`] holds the metadata required by the Specctra auto-router to +/// understand and enforce design rules across various net classes and layers in a PCB layout. +/// This struct encapsulates information about rules for individual nets, net classes, +/// layers, and their corresponding relationships. pub struct SpecctraMesadata { + + /// The default routing rule applied globally if no specific net class rule is defined. structure_rule: SpecctraRule, + // net class name -> rule + /// A map from net class names to their specific `SpecctraRule` constraints. + /// These rules are applied to all nets belonging to the respective net clas class_rules: HashMap, // layername <-> layer for Layout + /// A bidirectional map between layer indices and layer names, allowing translation + /// between index-based layers in the layout and user-defined layer names. pub layer_layername: BiHashMap, // netname <-> net for Layout + /// A bidirectional map between network indices and network names in the PCB layout, + /// providing an easy way to reference nets by name or index. pub net_netname: BiHashMap, // net -> netclass + /// A map that associates network indices with their respective net class names. + /// This is used to apply net class-specific routing rules to each net. net_netclass: HashMap, } + impl SpecctraMesadata { + /// Creates a [`SpecctraMesadata`] instance from a given `Pcb` reference. + /// + /// This function extracts the necessary metadata from the `Pcb` struct, such as + /// layer-to-layer name mappings, net-to-net name mappings, and net class rules. + /// pub fn from_pcb(pcb: &Pcb) -> Self { let layer_layername = BiHashMap::from_iter( pcb.structure @@ -81,6 +112,13 @@ impl SpecctraMesadata { } } + /// Retrieves the Specctra routing rule associated with a specified net ID. + /// + /// This function looks up the routing rule for a given net ID. It first checks if the net is + /// associated with a net class. If a net class is found, it retrieves the corresponding rule + /// from the class rules. If no class is associated, or if the class does not have a defined rule, + /// it defaults to the general structure rule. + /// pub fn get_rule(&self, net: usize) -> &SpecctraRule { if let Some(netclass) = self.net_netclass.get(&net) { self.class_rules