hdl_cat_ir/lib.rs
1//! Hardware intermediate representation.
2//!
3//! The central type is [`HdlGraph`] — a directed, typed, flat
4//! dataflow graph of hardware [`Instruction`]s that also implements
5//! `comp_cat_rs::collapse::free_category::Graph`.
6//!
7//! A compiled circuit is a sequence of gate invocations reading
8//! named [`WireId`]s and writing one new [`WireId`] each. Each
9//! [`Wire`] is tagged with a [`WireTy`]. Interpretation
10//! (simulation, Verilog emission) walks the instruction list.
11//!
12//! # Design
13//!
14//! comp-cat-rs's `Graph` models single-edge-per-morphism — each
15//! edge has exactly one source and one target vertex. Our
16//! [`Instruction`]s are multi-input: the graph view takes the
17//! first input as the source vertex and the output as the
18//! target. Secondary inputs live on the instruction itself.
19//! This keeps the `Graph` trait satisfiable without forcing
20//! tensor-product vertex types into the IR.
21//!
22//! Both representations are coherent: a `Path` through the
23//! `HdlGraph` corresponds to a sequential data-flow thread,
24//! while the full multi-port circuit structure is recoverable
25//! from the instruction list.
26//!
27//! # Example — building a graph by hand
28//!
29//! ```
30//! # fn main() -> Result<(), hdl_cat_error::Error> {
31//! use hdl_cat_ir::{BinOp, HdlGraphBuilder, Op, WireTy};
32//!
33//! // Compute `(a XOR b) AND c` using three input wires.
34//! let (b, a) = HdlGraphBuilder::new().with_wire(WireTy::Bit);
35//! let (b, bb) = b.with_wire(WireTy::Bit);
36//! let (b, c) = b.with_wire(WireTy::Bit);
37//! let (b, xor_out) = b.with_wire(WireTy::Bit);
38//! let (b, out) = b.with_wire(WireTy::Bit);
39//! let b = b.with_instruction(Op::Bin(BinOp::Xor), vec![a, bb], xor_out)?;
40//! let b = b.with_instruction(Op::Bin(BinOp::And), vec![xor_out, c], out)?;
41//! let graph = b.build();
42//!
43//! assert_eq!(graph.wires().len(), 5);
44//! assert_eq!(graph.instructions().len(), 2);
45//! # Ok(()) }
46//! ```
47//!
48//! # Example — interpreting the graph
49//!
50//! The `hdl-cat-sim` crate provides `interpret` which walks the
51//! instruction list, computing each wire's value from a supplied
52//! input environment.
53
54pub mod wire;
55pub mod op;
56pub mod instr;
57pub mod graph;
58pub mod builder;
59
60pub use builder::HdlGraphBuilder;
61pub use graph::HdlGraph;
62pub use instr::Instruction;
63pub use op::{BinOp, Op};
64pub use wire::{Wire, WireId, WireTy};