use std::collections::{HashMap, HashSet};
use crate::netlist::InstantiatedSignalId;
use super::graph::{DriverGraph, Partition};
use super::{CdcClassification, CdcConfidence, CdcEdge, ClockDomainId, RegionId};
pub(crate) fn classify_cdc_edges(graph: &DriverGraph, partitions: &[Partition]) -> Vec<CdcEdge> {
let mut region_of: HashMap<InstantiatedSignalId, RegionId> = HashMap::new();
let mut domain_of_region: HashMap<RegionId, Option<ClockDomainId>> = HashMap::new();
for p in partitions {
domain_of_region.insert(p.id, p.clock_domain);
for &n in p.nets.iter().chain(p.processes.iter()) {
region_of.insert(n, p.id);
}
}
let mut edges = Vec::new();
let mut seen: HashSet<(RegionId, RegionId, InstantiatedSignalId)> = HashSet::new();
for &(net_sig, proc_sig) in graph.read_edges() {
let (Some(&net_region), Some(&proc_region)) =
(region_of.get(&net_sig), region_of.get(&proc_sig))
else {
continue;
};
if net_region == proc_region {
continue;
}
let net_domain = domain_of_region.get(&net_region).copied().flatten();
let proc_domain = domain_of_region.get(&proc_region).copied().flatten();
let (Some(a), Some(b)) = (net_domain, proc_domain) else {
continue;
};
if a == b {
continue;
}
let key = (net_region, proc_region, net_sig);
if seen.insert(key) {
edges.push(CdcEdge {
from_region: net_region,
to_region: proc_region,
signal: net_sig,
classification: CdcClassification::Async,
confidence: CdcConfidence::StaticallyProven,
});
}
}
edges
}