WIP: fix simulator StructuralEq of enums
Some checks failed
/ test (pull_request) Failing after 1m25s

This commit is contained in:
Jacob Lifshay 2026-06-11 01:56:27 -07:00
parent 4bd6db3de8
commit 30ffd009f6
Signed by: programmerjake
SSH key fingerprint: SHA256:HnFTLGpSm4Q4Fj502oCFisjZSoakwEuTsJJMSke63RQ
4 changed files with 104 additions and 4 deletions

View file

@ -3974,10 +3974,13 @@ impl Compiler {
.compile_expr(instantiated_module_or_global, Expr::canonical(expr.arg()))
.map_ty(TraceAsString::from_canonical)
.inner(),
ExprEnum::StructuralEq(expr) => self.compile_expr(
instantiated_module_or_global,
Expr::canonical(expr.lhs().cast_to_bits().cmp_eq(expr.rhs().cast_to_bits())),
),
ExprEnum::StructuralEq(expr) => {
// FIXME: actually ignore enum padding
self.compile_expr(
instantiated_module_or_global,
Expr::canonical(expr.lhs().cast_to_bits().cmp_eq(expr.rhs().cast_to_bits())),
)
}
ExprEnum::ModuleIO(expr) => self
.compile_value(TargetInInstantiatedModuleOrGlobal::from_target(
instantiated_module_or_global,

View file

@ -3749,3 +3749,67 @@ at module-XXXXXXXXXX.rs:12:1: in InstantiatedModule(formal_counter: formal_count
}
}
}
#[hdl_module(outline_generated)]
pub fn enum_structural_eq() {
#[hdl]
let a: HdlOption<UInt<2>> = m.input();
#[hdl]
let b: HdlOption<UInt<2>> = m.input();
#[hdl]
let eq: Bool = m.output();
#[hdl]
let structural_eq: Bool = m.output();
#[hdl]
let bit_eq: Bool = m.output();
connect(eq, a.cmp_eq(b));
// explicitly use StructuralEq (though cmp_eq also uses it above)
connect(
structural_eq,
fayalite::expr::ops::StructuralEq::new(Expr::canonical(a), Expr::canonical(b)),
);
connect(bit_eq, a.cast_to_bits().cmp_eq(b.cast_to_bits()));
}
#[test]
fn test_enum_structural_eq() {
let _n = SourceLocation::normalize_files_for_tests();
let mut sim = Simulation::new(enum_structural_eq());
let _checked_vcd_output =
checked_vcd_output!(&mut sim, "tests/sim/expected/test_enum_structural_eq.vcd");
for a in 0..8u8 {
for b in 0..8u8 {
dbg!(a);
dbg!(b);
let a_sim_value = a.cast_to(UInt[3]).cast_bits_to(sim.io().a.ty());
let b_sim_value = b.cast_to(UInt[3]).cast_bits_to(sim.io().b.ty());
dbg!(&a_sim_value);
dbg!(&b_sim_value);
sim.write(sim.io().a, a_sim_value);
sim.write(sim.io().b, b_sim_value);
let a_with_zeroed_padding = if (a & 1) != 0 { a } else { 0 };
let b_with_zeroed_padding = if (b & 1) != 0 { b } else { 0 };
dbg!(a_with_zeroed_padding);
dbg!(b_with_zeroed_padding);
let expected_eq = a_with_zeroed_padding == b_with_zeroed_padding;
let expected_structural_eq = a_with_zeroed_padding == b_with_zeroed_padding;
let expected_bit_eq = a == b;
dbg!(expected_eq);
dbg!(expected_structural_eq);
dbg!(expected_bit_eq);
sim.advance_time(SimDuration::from_micros(1));
assert_eq!(sim.read_bool(sim.io().eq), expected_eq);
assert_eq!(
sim.read_bool(sim.io().structural_eq),
expected_structural_eq
);
assert_eq!(sim.read_bool(sim.io().bit_eq), expected_bit_eq);
}
}
let sim_debug = format!("{sim:#?}");
println!("#######\n{sim_debug}\n#######");
if sim_debug != include_str!("sim/expected/test_enum_structural_eq.txt") {
panic!();
}
}

View file

@ -0,0 +1,33 @@
$timescale 1 ps $end
$scope module enum_structural_eq $end
$scope struct a $end
$var string 1 +LxwI \$tag $end
$var wire 2 {bf!u HdlSome $end
$upscope $end
$scope struct b $end
$var string 1 O%@#" \$tag $end
$var wire 2 ]xpB, HdlSome $end
$upscope $end
$var wire 1 Yp4xI eq $end
$var wire 1 >R/<6 structural_eq $end
$var wire 1 ,}=e] bit_eq $end
$upscope $end
$enddefinitions $end
$dumpvars
sHdlNone\x20(0) +LxwI
b0 {bf!u
sHdlNone\x20(0) O%@#"
b0 ]xpB,
1Yp4xI
1>R/<6
1,}=e]
$end
#1000000
sHdlSome\x20(1) O%@#"
0Yp4xI
0>R/<6
0,}=e]
#2000000
sHdlNone\x20(0) O%@#"
b1 ]xpB,
#3000000