### Minimal Netlist Example Source: https://github.com/matth2k/safety-net/blob/main/README.md Demonstrates how to create a new netlist, insert inputs, instantiate a logical AND gate, and expose its output. This is a basic example for getting started with the library. ```rust use safety_net::{Gate, Netlist}; fn and_gate() -> Gate { Gate::new_logical( "AND".into(), vec!["A".into(), "B".into()], "Y".into(), ) } fn main() { let netlist = Netlist::new("example".to_string()); // Add the the two inputs let a = netlist.insert_input("a".into()); let b = netlist.insert_input("b".into()); // Instantiate an AND gate let instance = netlist .insert_gate(and_gate(), "inst_0".into(), &[a, b]) .unwrap(); // Make this AND gate an output instance.expose_with_name("y".into()); // Print the netlist println!("{netlist}"); } ``` -------------------------------- ### Run Simple Example Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/README.md Execute the 'simple' example provided in the repository to see Safety Net in action. ```bash cargo run --example simple ``` -------------------------------- ### Get Users Example Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/graph-analysis.md Returns all input ports driven by a specific driven net. Use this to trace net drivers to their consumers. ```rust for input_port in fanout.get_users(&driven_net) { println!("Drives input: {}", input_port.get_port()); } ``` -------------------------------- ### Minimal safety-net Circuit Example Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/getting-started.md A basic example demonstrating how to create a Netlist, insert inputs, define and insert a logical gate, expose an output, and verify the circuit. ```rust use safety_net::{Gate, Netlist}; fn main() -> Result<(), Box> { let netlist = Netlist::new("adder".to_string()); // Add inputs let a = netlist.insert_input("a".into()); let b = netlist.insert_input("b".into()); // Create gate let and = Gate::new_logical( "AND".into(), vec!["A".into(), "B".into()], "Y".into() ); // Instantiate with connections let result = netlist.insert_gate(and, "u1".into(), &[a, b])?; // Expose output result.expose_with_name("out".into()); // Print println!("{}", netlist); netlist.verify()?; Ok(()) } ``` -------------------------------- ### Get Net Users Example Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/graph-analysis.md Returns all circuit nodes that use a given net. Use this to find consumers of a specific net. ```rust let fanout = netlist.get_analysis::()?; for user in fanout.get_net_users(&some_net) { println!("Used by: {}", user); } ``` -------------------------------- ### Identifier Constructor Examples Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/types.md Demonstrates creating Identifier instances with automatic type classification based on input string format. ```rust let id1 = Identifier::new("clk".to_string()); // Normal let id2 = Identifier::new("\\signal+".to_string()); // Escaped let id3 = Identifier::new("bus[7]".to_string()); // BitSlice(7) ``` -------------------------------- ### Complete Ripple Carry Adder Example Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/getting-started.md Constructs a ripple carry adder of a specified bitwidth using Safety Net. This example showcases building sequential logic and handling multiple inputs and outputs. ```rust use safety_net::{Gate, Netlist, DrivenNet, format_id}; fn full_adder() -> Gate { Gate::new_logical_multi( "FA".into(), vec!["CIN".into(), "A".into(), "B".into()], vec!["S".into(), "COUT".into()] ) } fn build_ripple_adder(bitwidth: usize) -> Result>, Box> { let netlist = Netlist::new("ripple_adder".to_string()); // Create inputs let a = netlist.insert_input_escaped_logic_bus("a".to_string(), bitwidth); let b = netlist.insert_input_escaped_logic_bus("b".to_string(), bitwidth); let mut carry = netlist.insert_input("cin".into()); // Build adder chain for i in 0..bitwidth { let fa = netlist.insert_gate( full_adder(), format_id!("fa_{}", i), &[carry, a[i].clone(), b[i].clone()] )?; // Expose sum bit let sum_name = format_id!("s[{}]", i); fa.expose_with_name(sum_name); // Carry to next stage carry = fa.get_output(1); } // Final carry out carry.expose_with_name("cout".into()); netlist.verify()?; Ok(netlist) } fn main() -> Result<(), Box> { let netlist = build_ripple_adder(8)?; println!("{}", netlist); Ok(()) } ``` -------------------------------- ### NetMapper Apply Result Example Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/errors-and-utilities.md Shows how to use the result of the apply() method to determine the number of nets that were replaced. ```rust let replaced = mapper.apply()?; println!("Replaced {} nets", replaced.len()); ``` -------------------------------- ### Example Usage of format_id! Macro Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/errors-and-utilities.md Demonstrates how to use the format_id! macro to generate unique identifiers within a loop. ```rust use safety_net::format_id; for i in 0..4 { let id = format_id!("signal_{}", i); // signal_0, signal_1, etc. } ``` -------------------------------- ### Build FanOutTable Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/graph-analysis.md Instantiates the FanOutTable analysis. This is the standard way to get an analysis object from a netlist. ```rust let analysis = netlist.get_analysis::()?; ``` -------------------------------- ### NetMapper Batch Replacement Example Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/errors-and-utilities.md Demonstrates batch replacement of nets using NetMapper. This is useful for optimizing duplicated logic by replacing one instance with another. ```rust let mut mapper = NetMapper::new(&netlist)?; mapper.replace(old_net1.clone(), new_net.clone()); mapper.replace(old_net2.clone(), new_net.clone()); let replaced = mapper.apply()?; ``` -------------------------------- ### Identifier Emit Name Examples Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/types.md Shows how to format an Identifier for HDL output, preserving its original name and structure. ```rust Identifier::new("wire".to_string()).emit_name() // "wire" Identifier::new("\\signal+".to_string()).emit_name() // "\\signal+ " Identifier::new("bus[3]".to_string()).emit_name() // "bus[3]" ``` -------------------------------- ### Example Usage of filter_nodes! Macro Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/errors-and-utilities.md Shows how to use the filter_nodes! macro to find all AND gates in a netlist, and optionally with a guard clause for more specific filtering. ```rust use safety_net::{Gate, filter_nodes}; // Find all AND gates for and_gate in filter_nodes!(netlist, Gate) { // ... process AND gates } // With guard clause (if you have an enum variant Instantiable) for input_gate in filter_nodes!(netlist, MyGate::Input(_) if some_condition) { // ... } ``` -------------------------------- ### InputPort Methods Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/node-references.md Provides methods for managing and querying input ports, including getting and disconnecting drivers, and accessing port definitions. ```APIDOC ## InputPort Represents an input port of an instance that can be connected to a driver. ### Methods #### `get_driver() -> Option>` Returns the net currently driving this input. ### Response #### Success Response - **Return Value** (`Option>`) - The driving net, or None if unconnected #### `disconnect() -> Option>` Disconnects this input and returns the previous driver. ### Response #### Success Response - **Return Value** (`Option>`) - The previously connected driver #### `get_port() -> Net` Returns the port definition (its identifier and type). ### Response #### Success Response - **Return Value** (`Net`) - The port definition #### `get_input_num() -> usize` Returns the 0-based input port index. ### Response #### Success Response - **Return Value** (`usize`) - The input port index #### `connect(self, output: DrivenNet)` Connects this input to a driven net. ### Parameters #### Request Body - **output** (`DrivenNet`) - The driven net to connect to ### Request Example ```rust input_port.connect(driver); ``` #### `unwrap(self) -> NetRef` Returns the underlying NetRef of the node owning this input. ### Response #### Success Response - **Return Value** (`NetRef`) - The underlying NetRef ``` -------------------------------- ### Optimizing Duplicated Logic with NetMapper Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/errors-and-utilities.md Example of optimizing duplicated logic by building two identical sub-circuits and then replacing one with the other using NetMapper. This can lead to dead code elimination. ```rust use safety_net::netlist::rewriter::NetMapper; // Build two identical sub-circuits let sub1_output = /* ... */; let sub2_output = /* ... */; // Replace one with the other let mut mapper = NetMapper::new(&netlist)?; mapper.replace(sub2_output.clone(), sub1_output.clone()); mapper.apply()?; // Now sub1 and sub2 produce the same output (dead code can be cleaned) ``` -------------------------------- ### Get an input port by index Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/node-references.md Retrieves an InputPort wrapper for the input at the specified index. Panics if the node is a principal input. ```rust let input_a = node.get_input(0); if let Some(driver) = input_a.get_driver() { println!("Driven by: {}", driver); } ``` -------------------------------- ### Handle InstantiableError Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/errors-and-utilities.md An example demonstrating a potential `InstantiableError` when trying to insert a constant value into a netlist, specifically if the gate type does not implement `from_constant()`. ```rust let const_gate = netlist.insert_constant(Logic::True, "vdd".into()); // Err if Gate (or custom type) doesn't implement from_constant() ``` -------------------------------- ### Modify a Circuit Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/README.md Provides examples for modifying an existing circuit, including replacing net uses, deleting nodes, and cleaning up the netlist. ```rust // Replace uses netlist.replace_net_uses(old.clone(), &new)?; // Delete a node gate.delete_uses()?; // Clean up netlist.clean()?; ``` -------------------------------- ### Safety Net Project File Structure Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/README.md This snippet displays the directory structure of the Safety Net project. It shows the organization of source files, examples, and tests. ```tree safety-net/ ├── src/ │ ├── lib.rs # Crate root, re-exports │ ├── netlist.rs # Core Netlist, NetRef, DrivenNet types │ ├── circuit.rs # Identifier, Net, Object, Gate, Instantiable │ ├── logic.rs # Logic enum and operations │ ├── attribute.rs # Attribute, Parameter, AttributeFilter │ ├── error.rs # Error enum │ ├── graph.rs # Analysis traits, FanOutTable, CombDepthInfo, etc. │ └── util.rs # Internal utilities ├── examples/ │ ├── simple.rs # Minimal example │ ├── connections.rs # Manual connection │ ├── lut.rs # Custom gate type │ ├── variants.rs # Enum-based gate │ ├── dont_touch.rs # Attribute filtering │ └── pretty.rs # Graphviz output ├── tests/ # Test suite └── Cargo.toml ``` -------------------------------- ### Handle TypeError Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/errors-and-utilities.md An example illustrating a `TypeError` that can occur during connection verification when attempting to connect nets with incompatible data types. This typically happens in `Netlist::verify()`. ```rust // Creating a connection between incompatible types let two_state = Net::new("a".into(), DataType::boolean()); let four_state = Net::new("b".into(), DataType::logic()); // Connection might fail if types don't match ``` -------------------------------- ### Create and Expose a Circuit Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/README.md Demonstrates how to initialize a new Netlist, insert input ports, add a gate, expose its output, and verify the circuit's integrity. ```rust let netlist = Netlist::new("example".to_string()); let a = netlist.insert_input("a".into()); let b = netlist.insert_input("b".into()); let gate = netlist.insert_gate(/*...*/)?; gate.expose_with_name("output".into()); netlist.verify()?; ``` -------------------------------- ### Initialize Netlist with Rc> Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/errors-and-utilities.md Demonstrates the initialization of a Netlist and insertion of an input node, highlighting the use of Rc for internal reference management. ```rust let netlist = Netlist::new("circuit".to_string()); // netlist is Rc> let node = netlist.insert_input("a".into()); // node is DrivenNet, which holds Rc references internally ``` -------------------------------- ### set_attribute Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/node-references.md Sets an attribute without a value, for example, `(* dont_touch *)`. ```APIDOC ## `set_attribute(key: AttributeKey)` ### Description Sets an attribute without a value (e.g., `(* dont_touch *)`). ``` -------------------------------- ### Get Gate Name Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/types.md Retrieves the type name of the gate. ```rust get_gate_name(&self) -> &Identifier ``` -------------------------------- ### Get Net Identifier Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/types.md Retrieves a reference to the identifier associated with the Net. Does not consume the Net. ```rust let identifier = net.get_identifier(); ``` -------------------------------- ### Create Logical Gates Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/getting-started.md Demonstrates creating single-output and multi-output logical gates using Gate::new_logical and Gate::new_logical_multi. These gates can then be instantiated within a Netlist. ```rust use safety_net::{Gate, Netlist, DrivenNet}; let netlist = Netlist::new("example".to_string()); // Single-output gate let and_gate = Gate::new_logical( "AND".into(), vec!["A".into(), "B".into()], "Y".into() ); // Multi-output gate (e.g., Full Adder) let fa = Gate::new_logical_multi( "FA".into(), vec!["CIN".into(), "A".into(), "B".into()], vec!["S".into(), "COUT".into()] // Two outputs ); // Use gates let a = netlist.insert_input("a".into()); let b = netlist.insert_input("b".into()); let and_result = netlist.insert_gate(and_gate, "and1".into(), &[a.clone(), b.clone()])?; let fa_result = netlist.insert_gate(fa, "fa1".into(), &[a, b, /* cin */ ])?; ``` -------------------------------- ### Get Net Data Type Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/types.md Retrieves a reference to the data type of the Net. Does not consume the Net. ```rust let data_type = net.get_type(); ``` -------------------------------- ### Build Circuit with Error Handling Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/getting-started.md Demonstrates how to build a simple circuit and handle potential errors during gate insertion and verification. This is useful for validating circuit construction logic. ```rust use safety_net::Error; fn build_circuit() -> Result>, Error> { let netlist = Netlist::new("example".to_string()); let a = netlist.insert_input("a".into()); let b = netlist.insert_input("b".into()); // insert_gate can fail if arguments mismatch let gate = Gate::new_logical( "AND".into(), vec!["A".into(), "B".into()], "Y".into() ); let result = netlist.insert_gate(gate, "u1".into(), &[a, b])?; result.expose_with_name("out".into()); // Verify must succeed for valid output netlist.verify()?; Ok(netlist) } fn main() -> Result<(), Box> { match build_circuit() { Ok(netlist) => println!("{}", netlist), Err(Error::ArgumentMismatch(exp, got)) => { eprintln!("Wrong number of arguments: {} vs {}", exp, got); } Err(Error::NonuniqueNets(dupes)) => { eprintln!("Duplicate net names: {:?}", dupes); } Err(e) => eprintln!("Error: {}", e), } Ok(()) } ``` -------------------------------- ### Get the number of input ports Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/node-references.md Returns the total count of input ports for an instance node. ```rust let num_inputs = node.get_num_input_ports(); ``` -------------------------------- ### Analyze Circuit Properties Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/README.md Shows how to perform circuit analysis, such as calculating fan-out and determining critical path depth. ```rust let fanout = netlist.get_analysis::()?; for user in fanout.get_net_users(&net) { /* ... */ } let depth = netlist.get_analysis::()?; if let Some(path) = depth.build_critical_path() { /* ... */ } ``` -------------------------------- ### Get Netlist Module Name Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/netlist-api.md Retrieves a reference to the netlist module's name. This is a read-only operation. ```rust println!("Module: {}", netlist.get_name()); ``` -------------------------------- ### Create New Netlist Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/netlist-api.md Initializes a new reference-counted netlist with a specified module name. Use this to begin building a circuit. ```rust use safety_net::{Netlist, Gate}; let netlist = Netlist::::new("my_circuit".to_string()); ``` -------------------------------- ### Instantiate CombDepthInfo Analysis Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/graph-analysis.md Obtains an instance of the CombDepthInfo analysis from a netlist. This is a prerequisite for performing combinational depth calculations. ```rust let analysis = netlist.get_analysis::()?; ``` -------------------------------- ### Netlist::new Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/netlist-api.md Creates a new, reference-counted netlist with a specified module name. ```APIDOC ## Netlist::new ### Description Creates a new netlist with the given module name. ### Method `Netlist::new(name: String) -> Rc` ### Parameters #### Path Parameters - **name** (String) - Required - The module name of the netlist ### Response #### Success Response (200) - **Rc>** - A reference-counted netlist wrapped in Rc ### Request Example ```rust use safety_net::{Netlist, Gate}; let netlist = Netlist::::new("my_circuit".to_string()); ``` ``` -------------------------------- ### Get Single Output Port Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/types.md Returns the single output port of the gate. Panics if the gate has multiple outputs. ```rust get_single_output_port(&self) -> &Net ``` -------------------------------- ### expose_as_output Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/node-references.md Exposes this node's single output as a top-level output. Panics if the node drives multiple outputs. Returns the same node on success. ```APIDOC ## `expose_as_output(self) -> Result` ### Description Exposes this node's single output as a top-level output. ### Panics If the node drives multiple outputs. ### Returns `Result` — The same node on success ### Errors - `InputNeedsAlias`: This is a principal input ### Example ```rust result.expose_as_output()?; ``` ``` -------------------------------- ### Create Attribute Instance Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/types.md Demonstrates creating `Attribute` instances with and without a value. ```rust Attribute::new("dont_touch".to_string(), None); Attribute::new("synthesis".to_string(), Some("auto".to_string())); ``` -------------------------------- ### Get a DrivenNet wrapper for a specific output port Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/node-references.md Retrieves a DrivenNet wrapper for the output net at the specified index. ```rust let output_net = node.get_output(0); ``` -------------------------------- ### Identifier Concatenation Example Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/types.md Illustrates concatenating two identifiers using the Add operator, which handles special type combinations. ```rust let id1: Identifier = "a".into(); let id2: Identifier = "b".into(); let combined = id1 + id2; // "a_b" ``` -------------------------------- ### Consume Net to Get Identifier Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/types.md Consumes the Net instance and returns ownership of its identifier. The Net can no longer be used after this operation. ```rust let identifier = net.take_identifier(); ``` -------------------------------- ### Type Conversions Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/errors-and-utilities.md Demonstrates type conversions for common types like Identifier, Net, Logic, and DrivenNet using `into()` and `from()`. ```APIDOC ## Type Conversions ### From/Into for Common Types Demonstrates conversions for `Identifier`, `Net`, `Logic`, and `DrivenNet`. #### Identifier ```rust // Identifier let id: Identifier = "signal".into(); let id = Identifier::from("signal"); ``` #### Net ```rust // Net let net: Net = "signal".into(); // Four-state logic net let net = Net::from("signal"); ``` #### Logic ```rust // Logic let logic: Logic = true.into(); let logic = Logic::from(false); ``` #### DrivenNet from NetRef (single-output only) ```rust // DrivenNet from NetRef (single-output only) let driven: DrivenNet = node.clone().into(); let driven = DrivenNet::from(&node); ``` ``` -------------------------------- ### Generate and Visualize Netlist Graph Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/getting-started.md Create a Graphviz DOT representation of the netlist for visualization. Requires the 'graph' feature. ```rust #[cfg(feature = "graph")] { // Generate Graphviz DOT format let dot = netlist.dot_string()?; // Write to file std::fs::write("circuit.dot", dot)?; // Convert to SVG: // dot -Tsvg circuit.dot -o circuit.svg // Or dump directly netlist.dump_dot()?; // Creates circuit.dot in current directory } ``` -------------------------------- ### Filter Nodes with 'dont_touch' Attribute Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/errors-and-utilities.md Use `dont_touch_filter` to get an iterator for nodes marked with the 'dont_touch' attribute, preventing their optimization. ```rust use safety_net::dont_touch_filter; for protected_node in dont_touch_filter(&netlist) { println!("Cannot optimize: {}", protected_node); } ``` -------------------------------- ### Get Reference Count Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/graph-analysis.md Returns the number of references this table holds to a node. Used for detecting dangling references before deletion. ```rust pub fn get_ref_count(node: &NetRef) -> usize ``` -------------------------------- ### Net::new Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/types.md Creates a new Net with a specified identifier and data type. ```APIDOC ## Net::new ### Description Creates a new Net with a specified identifier and data type. ### Signature `Net::new(identifier: Identifier, data_type: DataType) -> Self` ### Parameters * **identifier** (Identifier) - The identifier for the net. * **data_type** (DataType) - The data type of the net. ### Example ```rust let net = Net::new("signal".into(), DataType::logic()); ``` ``` -------------------------------- ### Logic Helper Constructors Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/types.md Provides helper functions to create instances of Logic::True, Logic::False, Logic::X, and Logic::Z. ```rust pub fn r#true() -> Logic { Logic::True } pub fn r#false() -> Logic { Logic::False } pub fn dont_care() -> Logic { Logic::X } pub fn high_z() -> Logic { Logic::Z } ``` -------------------------------- ### Get the instantiable type of an instance Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/node-references.md Borrows the underlying instantiable type (gate/cell definition) if the NetRef is an instance. Returns None otherwise. ```rust if let Some(inst) = node.get_instance_type() { println!("Gate type: {}", inst.get_name()); } ``` -------------------------------- ### Get the instance name of a node Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/node-references.md Retrieves the instance name if the NetRef refers to an instance. Returns None if it's a principal input. ```rust if let Some(name) = node.get_instance_name() { println!("Instance: {}", name); } ``` -------------------------------- ### Create Net with Identifier and Data Type Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/types.md Use this constructor to create a Net instance when you have both the identifier and the specific data type. ```rust let net = Net::new("signal".into(), DataType::logic()); ``` -------------------------------- ### Get the identifier of a driven net Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/node-references.md Retrieves the name of the single net driven by a node. Panics if the node drives multiple outputs. ```rust let name = node.get_identifier(); ``` -------------------------------- ### Insert Constants (VDD/GND) Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/getting-started.md Demonstrates how to insert constant logic values (True for VDD, False for GND) into the Netlist. These constants can then be used as inputs to gates. ```rust use safety_net::Logic; let vdd = netlist.insert_constant(Logic::True, "vdd".into())?; let gnd = netlist.insert_constant(Logic::False, "gnd".into())?; // Use as inputs let gate = netlist.insert_gate(my_gate, "u1".into(), &[vdd, gnd])?; ``` -------------------------------- ### node_dfs() Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/netlist-api.md Performs a depth-first search traversal starting from a given node, visiting each node at most once. Returns an iterator over nodes in DFS order. ```APIDOC ## node_dfs(from: NetRef) -> impl Iterator> ### Description Depth-first search traversal starting from a node, visiting each node at most once. ### Parameters #### Path Parameters - **from** (NetRef) - Required - Starting node ### Returns impl Iterator> — Nodes in DFS order ### Example ```rust for node in netlist.node_dfs(output_node) { println!("Visiting: {}", node); } ``` ``` -------------------------------- ### Build MultiDiGraph Analysis Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/graph-analysis.md Instantiates the MultiDiGraph for analysis. Requires the netlist to have passed verification, ensuring unique names and type-correct connections. ```rust let analysis = netlist.get_analysis::()?; ``` -------------------------------- ### DrivenNet::connect Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/node-references.md Connects this output net to a specified input port. ```APIDOC ## DrivenNet::connect ### Description Connects this output to an input port. ### Method `connect(self, input: InputPort)` ### Parameters #### Path Parameters - **input** (`InputPort`) - The input port to connect to. ### Example ```rust output.connect(target_node.get_input(0)); ``` ``` -------------------------------- ### with_name Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/types.md Creates a new net with the same type but a different identifier. ```APIDOC ## with_name ### Description Creates a new net with the same type but a different identifier. ### Signature `with_name(&self, name: Identifier) -> Self` ### Parameters * **name** (Identifier) - The new identifier for the net. ### Returns A new Net instance with the updated identifier. ``` -------------------------------- ### Get the net driving a specific input port Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/node-references.md Returns the Net driven by the input at the specified index. Returns None if the input is unconnected. ```rust let driver_net = node.get_driver_net(0); ``` -------------------------------- ### Depth-First Search Traversal from a Node Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/netlist-api.md This snippet performs a depth-first search starting from a specified node, visiting each node at most once. It prints each visited node. ```rust for node in netlist.node_dfs(output_node) { println!("Visiting: {}", node); } ``` -------------------------------- ### Display and Debug Formatting Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/errors-and-utilities.md Shows how to use `Display` for human-readable output and `Debug` for diagnostic output for all public types. ```APIDOC ## Display and Debug Formatting All public types implement `Display` for human-readable output and `Debug` for diagnostic output. ### Display Formatting ```rust println!("{}", identifier); // Gate name or signal println!("{}", net); // Signal identifier println!("{}", logic); // "1'b0", "1'b1", "1'bx", "1'bz" println!("{}", parameter); // "42", "8'hFF", etc. println!("{}", netlist); // Verilog module text ``` ### Debug Formatting ```rust println!("{:?}", identifier); ``` ``` -------------------------------- ### Handle ParseError Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/errors-and-utilities.md Shows an example of a `ParseError` occurring when attempting to parse an invalid logic string. The `parse()` method returns a `Result` which can be an `Err(ParseError)`. ```rust let logic: Result = "1'b2".parse(); // Err(ParseError) ``` -------------------------------- ### first Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/netlist-api.md Returns an optional reference to the first circuit node in the netlist, if one exists. ```APIDOC ## first() -> Option> ### Description Returns a reference to the first circuit node, if any. ### Returns - **Option>** - An optional reference to the first circuit node. ``` -------------------------------- ### replace_uses_with Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/node-references.md Replaces all uses of this node's output with another net. Panics if this is a multi-output node. ```APIDOC ## `replace_uses_with(self, other: &DrivenNet) -> Result, Error>` ### Description Replaces all uses of this node's output with another net. ### Panics If this is a multi-output node. ### Example ```rust node.replace_uses_with(&replacement)?; ``` ``` -------------------------------- ### Query Gate Drivers Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/getting-started.md Retrieve information about what is driving a gate's inputs. You can get the specific driver node, the net driving it, or iterate through all drivers. ```rust // Get the driving node if let Some(driver) = gate.get_driver(0) { println!("Input 0 driven by: {}", driver); } // Get the driving net if let Some(net) = gate.get_driver_net(0) { println!("Net: {}", net); } // Iterate all drivers for (i, driver) in gate.drivers().enumerate() { if let Some(d) = driver { println!("Input {} driven by: {}", i, d); } else { println!("Input {} unconnected", i); } } ``` -------------------------------- ### Get the node driving a specific input port Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/node-references.md Returns the NetRef of the node driving the input at the specified index. Returns None if the input is unconnected. ```rust let driver_node = node.get_driver(0); ``` -------------------------------- ### Iterate Circuit Connections Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/getting-started.md Iterate through all connections within the netlist to understand signal flow. Shows source and target of each connection. ```rust for connection in netlist.connections() { println!( "{} drives {}", connection.src().as_net(), connection.target().get_port() ); } ``` -------------------------------- ### Debug Formatting for Safety Net Types Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/errors-and-utilities.md Shows how to use `println!` with `{:?}` for diagnostic output of Safety Net types. ```rust println!("{:?}", identifier); ``` -------------------------------- ### Get Combinational Depth of a Node Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/graph-analysis.md Retrieves the combinational depth classification for a given net node. Useful for understanding the logic level of individual components. ```rust let analysis = netlist.get_analysis::()?; for node in netlist.objects() { if let Some(CombDepthResult::Depth(d)) = analysis.get_comb_depth(&node) { println!("Logic level: {}", d); } } ``` -------------------------------- ### DFS Traversal in Rust Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/getting-started.md Perform Depth-First Search (DFS) traversals on the netlist, starting from outputs to inputs. This includes checking for combinational loops during the traversal. ```rust use safety_net::netlist::iter::{DFSIterator, NetDFSIterator}; // Traverse from outputs to inputs let output = netlist.objects().last().unwrap(); for node in netlist.node_dfs(output.clone()) { println!("{}", node); } // Check for cycles during traversal let mut dfs = DFSIterator::new(&netlist, output); while let Some(node) = dfs.next() { if dfs.check_cycles() { eprintln!("Combinational loop!"); break; } } ``` -------------------------------- ### expose_with_name Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/node-references.md Exposes this node as a top-level output with a specific name. Panics if the node drives multiple outputs. Returns the same node. ```APIDOC ## `expose_with_name(self, name: Identifier) -> Self` ### Description Exposes this node as a top-level output with a specific name. ### Panics If the node drives multiple outputs. ### Returns `Self` — The same node ### Example ```rust node.expose_with_name("output".into()); node.expose_with_name("output_alias".into()); // Create alias ``` ``` -------------------------------- ### Create Net from String Slice Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/types.md Provides a shorthand for creating four-state logic nets directly from a string slice using the `From` trait. ```rust let net: Net = "signal".into(); ``` -------------------------------- ### connections() Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/netlist-api.md Returns an iterator over all wire connections in the netlist. This allows for detailed inspection of how different components are wired together. ```APIDOC ## connections() ### Description Returns an iterator over all wire connections in the netlist. ### Method Iterator ### Returns impl Iterator> ### Example ```rust for conn in netlist.connections() { println!("{} drives {}", conn.src().as_net(), conn.net()); } ``` ``` -------------------------------- ### Net::new_logic Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/types.md Creates a new Net with a four-state logic type. ```APIDOC ## Net::new_logic ### Description Creates a new Net with a four-state logic type. ### Signature `Net::new_logic(name: Identifier) -> Self` ### Parameters * **name** (Identifier) - The name for the logic net. ### Example ```rust let net = Net::new_logic("data".into()); ``` ``` -------------------------------- ### Filter Nodes by Instance Type Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/netlist-api.md Use this snippet to find nodes whose instance type matches a given predicate. This example filters for nodes with the instance name 'AND'. ```rust let and_gates = netlist.matches(|inst| inst.get_name().to_string() == "AND"); ``` -------------------------------- ### From<&str> Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/types.md Shorthand for creating four-state logic nets from a string slice. ```APIDOC ## From<&str> ### Description Shorthand for creating four-state logic nets from a string slice. ### Example ```rust let net: Net = "signal".into(); ``` ``` -------------------------------- ### Get Maximum Combinational Depth Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/graph-analysis.md Retrieves the maximum combinational depth found in the entire circuit. Returns None if the circuit consists solely of combinational cycles or undefined states. ```rust let max_depth = analysis.get_max_depth(); ``` -------------------------------- ### NetMapper Constructor Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/errors-and-utilities.md Creates a new NetMapper for the netlist. Returns an error if netlist verification fails. ```rust pub struct NetMapper<'a, I: Instantiable> { /* ... */ } ``` -------------------------------- ### Get Underlying Petgraph Graph Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/graph-analysis.md Retrieve a reference to the petgraph directed graph for advanced analysis. Useful for algorithms like SCC detection, feedback arc sets, and topological sorting. ```rust let analysis = netlist.get_analysis::()?; let graph = analysis.get_graph(); use petgraph::algo::is_cyclic_directed; let has_cycles = is_cyclic_directed(graph); ``` -------------------------------- ### Display Formatting for Safety Net Types Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/errors-and-utilities.md Illustrates using `println!` with `{}` to display human-readable string representations of various Safety Net types. ```rust println!("{}", identifier); // Gate name or signal println!("{}", net); // Signal identifier println!("{}", logic); // "1'b0", "1'b1", "1'bx", "1'bz" println!("{}", parameter); // "42", "8'hFF", etc. println!("{}", netlist); // Verilog module text ``` -------------------------------- ### Logic Bitwise Operations Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/types.md Demonstrates bitwise AND, OR, and NOT operations on Logic values, showing their truth table semantics for four-state logic. ```rust let a = Logic::True; let b = Logic::False; let result = a & b; // Logic::False let result = a | b; // Logic::True let result = !a; // Logic::False ``` -------------------------------- ### FanOutTable::get_users Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/graph-analysis.md Fetches all input ports that are driven by a specific driven net. This is crucial for understanding which components are receiving signals from a particular net. ```APIDOC ## GET /graph/fanout/driven-net/users ### Description Returns all input ports driven by a specific driven net. ### Method GET ### Endpoint /graph/fanout/driven-net/users ### Parameters #### Query Parameters - **driven_net** (DrivenNet) - Required - The driven net to query ### Response #### Success Response (200) - **users** (Iterator>) - An iterator of input ports driven by the specified net ### Request Example ```rust for input_port in fanout.get_users(&driven_net) { println!("Drives input: {}", input_port.get_port()); } ``` ``` -------------------------------- ### DFS Traversal and Cycle Detection Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/graph-analysis.md Demonstrates how to use DFSIterator to traverse a netlist from an output node back to its inputs. Includes checking for cycles during traversal. ```rust use safety_net::netlist::iter::DFSIterator; // Traverse from an output back to inputs let output = netlist.objects().last().unwrap(); let mut dfs = DFSIterator::new(&netlist, output); while let Some(node) = dfs.next() { if dfs.check_cycles() { eprintln!("Cycle detected!"); break; } println!("Node: {}", node); } ``` -------------------------------- ### serialize() Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/netlist-api.md Serializes the netlist to JSON format, writing the output to the provided writer. This method requires the 'serde' feature to be enabled. ```APIDOC ## serialize(writer: impl std::io::Write) -> Result<(), serde_json::Error> *(requires `serde` feature)* ### Description Serializes the netlist to JSON format. ### Parameters #### Path Parameters - **writer** (impl std::io::Write) - Required - The writer to serialize to. ### Returns Result<(), serde_json::Error> ``` -------------------------------- ### Logic Constructors Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/types.md Provides helper functions to create instances of the Logic enum: True, False, X (don't care), and Z (high impedance). ```APIDOC ## Helper Functions ### `r#true()` Creates a `Logic::True` instance. ### `r#false()` Creates a `Logic::False` instance. ### `dont_care()` Creates a `Logic::X` (Unknown/don't care) instance. ### `high_z()` Creates a `Logic::Z` (High impedance) instance. ``` -------------------------------- ### Expose Node Output with Name Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/node-references.md Exposes a node as a top-level output with a specific name. Panics if the node drives multiple outputs. ```rust node.expose_with_name("output".into()); node.expose_with_name("output_alias".into()); // Create alias ``` -------------------------------- ### outputs() Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/netlist-api.md Returns a vector of (driving node, output net name) pairs for all exposed outputs. This method helps in understanding the netlist's outputs and their sources. ```APIDOC ## outputs() ### Description Returns a vector of (driving node, output net name) pairs for all exposed outputs. ### Method Vec ### Returns Vec<(DrivenNet, Net)> ``` -------------------------------- ### Insert Gate Disconnected and Connect Manually Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/getting-started.md Shows how to insert a gate into the Netlist without immediate input connections, allowing for manual connection of inputs and outputs later. This provides fine-grained control over circuit wiring. ```rust // Insert without connecting inputs let gate = netlist.insert_gate_disconnected( Gate::new_logical("OR".into(), vec!["A".into(), "B".into()], "Y".into()), "or1".into() ); // Connect inputs one by one gate.get_input(0).connect(input_a.clone()); gate.get_input(1).connect(input_b.clone()); // Or get the outputs and connect them let output = gate.get_output(0); output.connect(next_gate.get_input(0)); ``` -------------------------------- ### Iterate Through Circuit Elements Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/README.md Illustrates various methods for iterating over circuit components, including all objects, connections, specific gate types, and nodes via DFS. ```rust for node in netlist.objects() { /* all nodes */ } for conn in netlist.connections() { /* all wires */ } for gate in netlist.matches(|i| i.get_name() == "AND") { /* AND gates */ } for node in netlist.node_dfs(start) { /* DFS from start */ } ``` -------------------------------- ### Serialize and Deserialize Netlist to JSON Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/getting-started.md Save and load netlist data using JSON format. Requires the 'serde' feature to be enabled. ```rust #[cfg(feature = "serde")] { use std::fs::File; use safety_net::netlist::serde::{netlist_serialize, netlist_deserialize}; // Save to JSON let file = File::create("circuit.json")?; netlist_serialize(netlist.clone(), file)?; // Load from JSON let file = File::open("circuit.json")?; let loaded: Rc> = netlist_deserialize(file)?; } ``` -------------------------------- ### Parameter BitVec Constructor Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/types.md Creates a Parameter::BitVec variant. Panics if the specified size is greater than 64. ```rust Parameter::bitvec(size: usize, val: u64) -> Self ``` -------------------------------- ### Create New Net with Different Identifier Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/types.md Returns a new Net instance with the same data type but a different identifier. The original Net remains unchanged. ```rust let new_net = net.with_name(new_identifier); ``` -------------------------------- ### Connect Gate Input Through InputPort Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/getting-started.md Connect a gate's input port to a driver (e.g., a net). This method is useful when you have a reference to the input port and the driver. ```rust let input_port = gate.get_input(0); let driver = some_net.clone(); input_port.connect(driver); ``` -------------------------------- ### Expose Net as Output Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/netlist-api.md Exposes a driven net as a top-level output using its current name. This is useful when the net already has a suitable name. ```rust let result = netlist.insert_gate(gate, "gate1".into(), &[a, b])?; result.expose_as_output()?; // Uses the gate's output net name ``` -------------------------------- ### NetMapper Apply Operation Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/errors-and-utilities.md Applies all accumulated replacements to the netlist in a single pass. Returns a list of nets that were replaced. Errors if replacement would create dangling references. ```rust fn apply(self) -> Result>, Error> ``` -------------------------------- ### Perform Batch Net Replacements Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/getting-started.md Efficiently replace multiple nets within a netlist using the NetMapper utility. Applies all replacements in a single pass. ```rust use safety_net::netlist::rewriter::NetMapper; // Replace multiple nets efficiently let mut mapper = NetMapper::new(&netlist)?; mapper.replace(old_net1.clone(), new_net.clone()); mapper.replace(old_net2.clone(), new_net.clone()); mapper.replace(old_net3.clone(), new_net.clone()); let replaced = mapper.apply()?; println!("Replaced {} nets in single pass", replaced.len()); ``` -------------------------------- ### DrivenNet::expose_with_name Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/node-references.md Exposes this net as a top-level output with a given name. ```APIDOC ## DrivenNet::expose_with_name ### Description Exposes this net as a top-level output with a specific name. ### Method `expose_with_name(self, name: Identifier) -> Self` ### Parameters #### Path Parameters - **name** (`Identifier`) - The desired name for the top-level output. ### Returns `Self` - The same driven net, now exposed. ### Example ```rust driven_net.expose_with_name("output".into()); ``` ``` -------------------------------- ### InputPort Operations Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/README.md Handle type for an input port of an instance, enabling connection management. ```APIDOC ## InputPort Reference `InputPort` represents an input port of an instance. It provides methods for querying port details and managing connections. ### Connection - **`get_driver()`**: Returns the `NetRef` that is currently driving this input port. - **`disconnect()`**: Disconnects the input port from its current driver. - **`connect(driver_net: &NetRef)`**: Connects this input port to a specified driver net. ### Queries - **`get_port()`**: Returns the port number of this input port. - **`get_input_num()`**: Returns the input number associated with this port. ``` -------------------------------- ### Expose Gate Outputs Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/getting-started.md Make a gate's output accessible externally. You can expose a single output by name, use the net's name, or create multiple aliases for multi-output gates. ```rust // Single output by name result.expose_with_name("output".into()); // Single output using net name result.expose_as_output()?; // Multiple aliases (multi-output gate) result.expose_net(&result.get_net(0))?; // Output 0 as primary name result.expose_net_with_name(result.get_output(0), "s".into()); // Alias ``` -------------------------------- ### Create Multi-Output Logical Gate Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/types.md Constructs a gate with multiple outputs, accepting input and output port names. ```rust let fa = Gate::new_logical_multi( "FA".into(), vec!["A".into(), "B".into(), "CIN".into()], vec!["S".into(), "COUT".into()] ); ``` -------------------------------- ### Parameter Real Constructor Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/types.md Creates a Parameter::Real variant with an f32 value. ```rust Parameter::real(r: f32) -> Self ``` -------------------------------- ### Connect Gate Input by Index Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/getting-started.md Connect specific inputs of a gate using their index. This is a straightforward way to wire up gates when the input order is known. ```rust let gate = netlist.insert_gate_disconnected(/*...*/); gate.get_input(0).connect(driver1); gate.get_input(1).connect(driver2); ``` -------------------------------- ### Graph Analysis with Rust (Graph Feature) Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/getting-started.md When the 'graph' feature is enabled, you can perform advanced graph analysis, including finding strongly connected components (loops) and feedback arcs, and exporting the graph to Graphviz format. ```rust #[cfg(feature = "graph")] { use safety_net::graph::MultiDiGraph; let analysis = netlist.get_analysis::()?; // Find strongly connected components (loops) for scc in analysis.sccs() { if scc.len() > 1 { println!("Found loop with {} nodes:", scc.len()); } } // Find feedback arcs for edge in analysis.greedy_feedback_arcs() { println!("Break: {}", edge); } // Export to graphviz let dot = netlist.dot_string()?; println!("{}", dot); } ``` -------------------------------- ### Analyze Fan-out in Rust Source: https://github.com/matth2k/safety-net/blob/main/_autodocs/getting-started.md Use the `FanOutTable` analysis to find all users of a specific net and check if a net is currently in use. This helps understand net connectivity. ```rust use safety_net::graph::FanOutTable; let fanout = netlist.get_analysis::()?; // Find all uses of a net for user in fanout.get_net_users(&some_net) { println!("Used by: {}", user); } // Check if net is used if fanout.net_has_uses(&some_net) { println!("In use"); } ```