1use bitloom_hir::{FrozenHir, PortValues};
7
8use crate::{AbstractionView, PortMismatch, Sim, check_mixed_both};
9
10#[derive(Debug, Clone, PartialEq, Eq)]
12pub enum EquivStatus {
13 Pass {
14 cycles: usize,
15 },
16 Fail {
17 cycle: usize,
18 mismatches: Vec<PortMismatch>,
19 },
20}
21
22impl EquivStatus {
23 pub fn is_pass(&self) -> bool {
24 matches!(self, Self::Pass { .. })
25 }
26}
27
28pub fn check_functional_equiv<A: AbstractionView>(
32 hir: FrozenHir,
33 abs: &mut A,
34 stimuli: impl IntoIterator<Item = PortValues>,
35) -> EquivStatus {
36 let mut sim = Sim::new(hir);
37 let mut cycles = 0usize;
38 for inputs in stimuli {
39 match check_mixed_both(&mut sim, abs, inputs) {
40 Ok(()) => cycles += 1,
41 Err(mismatches) => {
42 return EquivStatus::Fail {
43 cycle: cycles,
44 mismatches,
45 };
46 }
47 }
48 }
49 EquivStatus::Pass { cycles }
50}
51
52pub fn check_functional_equiv_generated(
57 hir: FrozenHir,
58 stimuli: impl IntoIterator<Item = PortValues>,
59) -> EquivStatus {
60 crate::check_generated_bridge(hir, stimuli)
61}
62
63pub fn reset_then_run(n: usize) -> Vec<PortValues> {
65 let mut out = Vec::with_capacity(n + 1);
66 let mut rst = PortValues::default();
67 rst.set("rst", 1);
68 out.push(rst);
69 for _ in 0..n {
70 let mut pv = PortValues::default();
71 pv.set("rst", 0);
72 out.push(pv);
73 }
74 out
75}