diff --git a/crates/fayalite/src/sim/compiler.rs b/crates/fayalite/src/sim/compiler.rs index 282507f..a098151 100644 --- a/crates/fayalite/src/sim/compiler.rs +++ b/crates/fayalite/src/sim/compiler.rs @@ -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, diff --git a/crates/fayalite/tests/sim.rs b/crates/fayalite/tests/sim.rs index 223c4bc..343b87b 100644 --- a/crates/fayalite/tests/sim.rs +++ b/crates/fayalite/tests/sim.rs @@ -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> = m.input(); + #[hdl] + let b: HdlOption> = 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!(); + } +} diff --git a/crates/fayalite/tests/sim/expected/test_enum_structural_eq.txt b/crates/fayalite/tests/sim/expected/test_enum_structural_eq.txt new file mode 100644 index 0000000..e69de29 diff --git a/crates/fayalite/tests/sim/expected/test_enum_structural_eq.vcd b/crates/fayalite/tests/sim/expected/test_enum_structural_eq.vcd new file mode 100644 index 0000000..ddb10e7 --- /dev/null +++ b/crates/fayalite/tests/sim/expected/test_enum_structural_eq.vcd @@ -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