pub mod caches;
pub mod coherence;
pub mod commit;
pub mod ddr5;
pub mod fu;
pub mod gate;
pub mod pipeline;
pub mod predictors;
pub mod program;
use std::collections::BTreeSet;
use crate::Simulator;
use crate::sim::stats::Histogram;
#[derive(Default)]
pub struct Recorder {
checked: BTreeSet<String>,
}
impl Recorder {
pub fn expect(&mut self, sim: &Simulator, path: &str, expected: u64, context: &str) {
assert_eq!(read(sim, path), expected as f64, "{context}: {path}");
self.note(path);
}
pub fn expect_ratio(&mut self, sim: &Simulator, path: &str, expected: f64, context: &str) {
let actual = read(sim, path);
assert!((actual - expected).abs() < 1e-9, "{context}: {path} is {actual}, not {expected}");
self.note(path);
}
pub fn read(&mut self, sim: &Simulator, path: &str) -> u64 {
self.note(path);
read(sim, path) as u64
}
pub fn histogram(&mut self, sim: &Simulator, path: &str) -> Histogram {
self.note(path);
sim.stats()
.histogram_at(path)
.cloned()
.unwrap_or_else(|| panic!("{path} has recorded nothing"))
}
fn note(&mut self, path: &str) {
let _ = self.checked.insert(path.to_owned());
}
}
fn read(sim: &Simulator, path: &str) -> f64 {
sim.stats().get(path).unwrap_or_else(|| panic!("{path} is not a registered stat"))
}
macro_rules! accounting_checks {
($($check:ident),* $(,)?) => {
#[cfg(test)]
mod each {
$(
#[test]
fn $check() {
super::$check(&mut crate::tests::integration::stats_accounting::Recorder::default());
}
)*
}
pub const CHECKS: &[fn(&mut crate::tests::integration::stats_accounting::Recorder)] =
&[$($check),*];
};
}
pub(crate) use accounting_checks;