From 04752c5037761626e58cc91e7c2e78aa231b7904 Mon Sep 17 00:00:00 2001 From: Jacob Lifshay Date: Wed, 25 Sep 2024 21:50:49 -0700 Subject: [PATCH] add test for connect_any with nested enums with different-sized variant bodies simplify_enums is currently broken in that case --- crates/fayalite/tests/module.rs | 130 ++++++++++++++++++++++++++++++++ 1 file changed, 130 insertions(+) diff --git a/crates/fayalite/tests/module.rs b/crates/fayalite/tests/module.rs index 4139ee1..cddf808 100644 --- a/crates/fayalite/tests/module.rs +++ b/crates/fayalite/tests/module.rs @@ -3234,3 +3234,133 @@ circuit check_formal: "#, }; } + +#[hdl] +pub enum OneOfThree { + A(A), + B(B), + C(C), +} + +#[hdl_module(outline_generated)] +pub fn check_enum_connect_any() { + #[hdl] + let index: UInt<2> = m.input(); + #[hdl] + let i0: OneOfThree, HdlOption>, Bool> = m.input(); + #[hdl] + let i1: OneOfThree, HdlOption>, Bool> = m.input(); + #[hdl] + let i2: OneOfThree, HdlOption>, Bool> = m.input(); + #[hdl] + let i3: OneOfThree, HdlOption>, Bool> = m.input(); + #[hdl] + let o0: OneOfThree, HdlOption>, Bool> = m.output(); + #[hdl] + let o1: OneOfThree, HdlOption>, Bool> = m.output(); + #[hdl] + let o2: OneOfThree, HdlOption>, Bool> = m.output(); + #[hdl] + let o3: OneOfThree, HdlOption>, Bool> = m.output(); + #[hdl] + if index.cmp_eq(0u8) { + connect_any(o0, i0); + connect_any(o1, i1); + connect_any(o2, i2); + connect_any(o3, i3); + } else if index.cmp_eq(1u8) { + connect_any(o0, i1); + connect_any(o1, i2); + connect_any(o2, i3); + connect_any(o3, i0); + } else if index.cmp_eq(2u8) { + connect_any(o0, i2); + connect_any(o1, i3); + connect_any(o2, i0); + connect_any(o3, i1); + } else { + connect_any(o0, i3); + connect_any(o1, i0); + connect_any(o2, i1); + connect_any(o3, i2); + } +} + +#[cfg(todo)] +#[test] +fn test_enum_connect_any() { + let _n = SourceLocation::normalize_files_for_tests(); + let m = check_enum_connect_any(); + dbg!(m); + #[rustfmt::skip] // work around https://github.com/rust-lang/rustfmt/issues/6161 + assert_export_firrtl! { + m => + "/test/check_enum_connect_any.fir": r"FIRRTL version 3.2.0 +circuit check_enum_connect_any: + type Ty0 = {|HdlNone, HdlSome: SInt<0>|} + type Ty1 = {|A: UInt<0>, B: Ty0, C: UInt<1>|} + type Ty2 = {|HdlNone, HdlSome: SInt<1>|} + type Ty3 = {|A: UInt<1>, B: Ty2, C: UInt<1>|} + type Ty4 = {|HdlNone, HdlSome: SInt<2>|} + type Ty5 = {|A: UInt<2>, B: Ty4, C: UInt<1>|} + type Ty6 = {|HdlNone, HdlSome: SInt<3>|} + type Ty7 = {|A: UInt<3>, B: Ty6, C: UInt<1>|} + module check_enum_connect_any: @[module-XXXXXXXXXX.rs 1:1] + input index: UInt<2> @[module-XXXXXXXXXX.rs 2:1] + input i0: Ty1 @[module-XXXXXXXXXX.rs 3:1] + input i1: Ty3 @[module-XXXXXXXXXX.rs 4:1] + input i2: Ty5 @[module-XXXXXXXXXX.rs 5:1] + input i3: Ty7 @[module-XXXXXXXXXX.rs 6:1] + output o0: Ty1 @[module-XXXXXXXXXX.rs 7:1] + output o1: Ty3 @[module-XXXXXXXXXX.rs 8:1] + output o2: Ty5 @[module-XXXXXXXXXX.rs 9:1] + output o3: Ty7 @[module-XXXXXXXXXX.rs 10:1] + when eq(index, UInt<8>(0h0)): @[module-XXXXXXXXXX.rs 11:1] + connect o0, i0 @[module-XXXXXXXXXX.rs 12:1] + connect o1, i1 @[module-XXXXXXXXXX.rs 13:1] + connect o2, i2 @[module-XXXXXXXXXX.rs 14:1] + connect o3, i3 @[module-XXXXXXXXXX.rs 15:1] + else when eq(index, UInt<8>(0h1)): @[module-XXXXXXXXXX.rs 16:1] + connect o0, i1 @[module-XXXXXXXXXX.rs 17:1] + connect o1, i2 @[module-XXXXXXXXXX.rs 18:1] + connect o2, i3 @[module-XXXXXXXXXX.rs 19:1] + connect o3, i0 @[module-XXXXXXXXXX.rs 20:1] + else when eq(index, UInt<8>(0h2)): @[module-XXXXXXXXXX.rs 21:1] + connect o0, i2 @[module-XXXXXXXXXX.rs 22:1] + connect o1, i3 @[module-XXXXXXXXXX.rs 23:1] + connect o2, i0 @[module-XXXXXXXXXX.rs 24:1] + connect o3, i1 @[module-XXXXXXXXXX.rs 25:1] + else: + connect o0, i3 @[module-XXXXXXXXXX.rs 26:1] + connect o1, i0 @[module-XXXXXXXXXX.rs 27:1] + connect o2, i1 @[module-XXXXXXXXXX.rs 28:1] + connect o3, i2 @[module-XXXXXXXXXX.rs 29:1] +", + }; + // FIXME: simplify_enums is broken when connecting enums that contain + // UInt/SInt where their widths don't match. it should recurse into the + // enum bodies so it can properly sign/zero-extend or truncate the + // contained UInt/SInt fields. + let orig_m = m.canonical().intern(); + let m = simplify_enums(orig_m, SimplifyEnumsKind::SimplifyToEnumsWithNoBody).unwrap(); + dbg!(m); + #[rustfmt::skip] // work around https://github.com/rust-lang/rustfmt/issues/6161 + assert_export_firrtl! { + m => + "/test/check_enum_connect_any.fir": r"TODO", + }; + let m = simplify_enums(orig_m, SimplifyEnumsKind::ReplaceWithBundleOfUInts).unwrap(); + dbg!(m); + #[rustfmt::skip] // work around https://github.com/rust-lang/rustfmt/issues/6161 + assert_export_firrtl! { + m => + "/test/check_enum_connect_any.fir": r"TODO", + }; + let m = simplify_enums(orig_m, SimplifyEnumsKind::ReplaceWithUInt).unwrap(); + dbg!(m); + #[rustfmt::skip] // work around https://github.com/rust-lang/rustfmt/issues/6161 + assert_export_firrtl! { + m => + "/test/check_enum_connect_any.fir": r"TODO", + }; +}