1use std::collections::BTreeSet;
7
8use celox_design::{ModuleId, VarAtomBase};
9use fxhash::{FxHashMap as HashMap, FxHashSet as HashSet};
10
11pub mod const_inline;
12mod lower;
13mod node;
14mod node_facts;
15mod node_rules;
16mod path;
17pub mod range_store;
18pub mod scheduler;
19mod symbolic_store;
20mod symbolic_verify;
21
22#[doc(hidden)]
23pub use lower::matches_slt_or_scan_group;
24pub use lower::{SLTToSIRLowerer, matches_slt_count_idiom};
25pub use node::{
26 NodeId, SLTForEffect, SLTForFoldGroupState, SLTForFoldResult, SLTForUpdate, SLTIndex,
27 SLTIndexKind, SLTLoopBound, SLTNode, SLTNodeArena, SLTNodeArenaEditError, SLTStepOp,
28};
29pub use node_facts::{SLTNodeFacts, SLTNodeFactsError};
30pub use path::{LogicPath, LogicPathId, LogicPathTarget};
31pub use range_store::{RangeStore, RangeStoreError};
32pub use scheduler::FfAccessSummary;
33pub use symbolic_store::SymbolicStore;
34pub use symbolic_verify::verify_symbolic_roots;
35
36pub fn get_width<A: std::hash::Hash + Eq + Clone>(node: NodeId, arena: &SLTNodeArena<A>) -> usize {
38 arena
39 .width(node)
40 .unwrap_or_else(|| panic!("SLT node id n{} is outside the arena", node.0))
41}
42
43pub type BoundaryMap<A> = HashMap<A, BTreeSet<usize>>;
49
50#[derive(Clone, Debug)]
52pub struct CombObserver<A> {
53 pub site_id: u32,
54 pub activation_group: u32,
55 pub guard: Option<NodeId>,
56 pub args: Vec<NodeId>,
57 pub loop_runner: Option<NodeId>,
58 pub sensitivity: Vec<VarAtomBase<A>>,
59 pub local_inputs: Vec<(A, NodeId)>,
60 pub observed_inputs: Vec<VarAtomBase<A>>,
61 pub position_inputs: Vec<VarAtomBase<A>>,
62 pub preceding_writes: Vec<VarAtomBase<A>>,
63 pub written_before: Vec<VarAtomBase<A>>,
64 pub written_input_atoms: Vec<VarAtomBase<A>>,
65 pub written_inputs: Vec<A>,
66 pub captured_in_loop: bool,
67}
68
69#[derive(
70 Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, serde::Serialize, serde::Deserialize,
71)]
72pub enum GlueAddrBase<V> {
73 Parent(V),
74 Child(V),
75}
76
77impl<V: Copy> GlueAddrBase<V> {
78 pub fn var_id(&self) -> V {
79 match self {
80 GlueAddrBase::Parent(value) | GlueAddrBase::Child(value) => *value,
81 }
82 }
83}
84
85impl<V: std::fmt::Display> std::fmt::Display for GlueAddrBase<V> {
86 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
87 match self {
88 GlueAddrBase::Parent(value) => write!(f, "GlueAddr::Parent({value})"),
89 GlueAddrBase::Child(value) => write!(f, "GlueAddr::Child({value})"),
90 }
91 }
92}
93
94#[derive(Clone, Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
95#[serde(bound(
96 serialize = "V: serde::Serialize",
97 deserialize = "V: serde::Deserialize<'de> + std::hash::Hash + Eq + Clone"
98))]
99pub struct GlueBlockBase<V: std::hash::Hash + Eq + Clone> {
100 pub module_id: ModuleId,
101 pub input_ports: Vec<(Vec<V>, LogicPath<GlueAddrBase<V>>)>,
102 pub output_ports: Vec<(Vec<V>, LogicPath<GlueAddrBase<V>>)>,
103 pub arena: SLTNodeArena<GlueAddrBase<V>>,
104}
105
106#[cfg(test)]
107mod tests {
108 use super::*;
109
110 #[test]
111 fn symbolic_store_key_is_a_semantic_address_not_a_frontend_id() {
112 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
113 struct DesignAddress(u32);
114
115 let mut store = SymbolicStore::<DesignAddress, u32>::default();
116 store.insert(DesignAddress(7), RangeStore::new(None, 8));
117
118 assert!(store.contains_key(&DesignAddress(7)));
119 }
120}