// SPDX-License-Identifier: LGPL-3.0-or-later // See Notices.txt for copyright information use fayalite::{ assert_export_firrtl, firrtl::ExportOptions, intern::Intern, module::transform::simplify_enums::SimplifyEnumsKind, prelude::*, ty::StaticType, }; use serde_json::json; #[hdl(outline_generated)] pub enum TestEnum { A, B(UInt<8>), C(Array), } #[hdl_module(outline_generated)] pub fn my_module(width: usize) { #[hdl] let clk: Clock = m.input(); #[hdl] let rst: SyncReset = m.input(); #[hdl] let clock_domain: ClockDomain = wire(); connect(clock_domain.clk, clk); connect(clock_domain.rst, rst.to_reset()); #[hdl] let i: UInt<8> = m.input(); #[hdl] let o: Array, 3> = m.output(); #[hdl] let i2: UInt = m.input(UInt[width]); #[hdl] let o2: UInt = m.output(UInt[width]); #[hdl] let o3: (UInt<32>, SInt<5>) = m.output(); connect( o3, #[hdl] (5_hdl_u32, -3_hdl_i5), ); #[hdl] let m2 = instance(module2()); #[hdl] let r_reg: UInt<8> = reg_builder().clock_domain(clock_domain).reset(8_hdl_u8); connect(m2.i, i); connect(r_reg, m2.o); connect( o, #[hdl] [r_reg, r_reg, b'\r'_hdl], ); connect(o[1], 30_hdl_u8); connect(o2, i2); #[hdl] let o4: TestEnum = m.output(); connect( o4, TestEnum.C( #[hdl] [false, true, false], ), ); } #[hdl_module(outline_generated)] pub fn module2() { #[hdl] let i: UInt<8> = m.input(); #[hdl] let o: UInt<8> = m.output(); #[hdl] let w: UInt<8> = wire(); connect(w, i); connect(o, w); } #[test] fn test_mymodule() { let _n = SourceLocation::normalize_files_for_tests(); let m = my_module(3); dbg!(m); #[rustfmt::skip] // work around https://github.com/rust-lang/rustfmt/issues/6161 assert_export_firrtl! { m => options: ExportOptions { simplify_enums: None, ..ExportOptions::default() }, "/test/my_module.fir": r"FIRRTL version 3.2.0 circuit my_module: type Ty0 = {`0`: UInt<32>, `1`: SInt<5>} type Ty1 = {|A, B: UInt<8>, C: UInt<1>[3]|} type Ty2 = {clk: Clock, rst: Reset} type Ty3 = {flip i: UInt<8>, o: UInt<8>} module my_module: @[module-XXXXXXXXXX.rs 1:1] input clk: Clock @[module-XXXXXXXXXX.rs 2:1] input rst: UInt<1> @[module-XXXXXXXXXX.rs 3:1] input i: UInt<8> @[module-XXXXXXXXXX.rs 7:1] output o: UInt<8>[3] @[module-XXXXXXXXXX.rs 8:1] input i2: UInt<3> @[module-XXXXXXXXXX.rs 9:1] output o2: UInt<3> @[module-XXXXXXXXXX.rs 10:1] output o3: Ty0 @[module-XXXXXXXXXX.rs 11:1] output o4: Ty1 @[module-XXXXXXXXXX.rs 20:1] wire clock_domain: Ty2 @[module-XXXXXXXXXX.rs 4:1] connect clock_domain.clk, clk @[module-XXXXXXXXXX.rs 5:1] connect clock_domain.rst, rst @[module-XXXXXXXXXX.rs 6:1] wire _bundle_literal_expr: Ty0 connect _bundle_literal_expr.`0`, UInt<32>(0h5) connect _bundle_literal_expr.`1`, SInt<5>(-0h3) connect o3, _bundle_literal_expr @[module-XXXXXXXXXX.rs 12:1] inst m2 of module2 @[module-XXXXXXXXXX.rs 13:1] regreset r_reg: UInt<8>, clock_domain.clk, clock_domain.rst, UInt<8>(0h8) @[module-XXXXXXXXXX.rs 14:1] connect m2.i, i @[module-XXXXXXXXXX.rs 15:1] connect r_reg, m2.o @[module-XXXXXXXXXX.rs 16:1] wire _array_literal_expr: UInt<8>[3] connect _array_literal_expr[0], r_reg connect _array_literal_expr[1], r_reg connect _array_literal_expr[2], UInt<8>(0hD) connect o, _array_literal_expr @[module-XXXXXXXXXX.rs 17:1] connect o[1], UInt<8>(0h1E) @[module-XXXXXXXXXX.rs 18:1] connect o2, i2 @[module-XXXXXXXXXX.rs 19:1] wire _array_literal_expr_1: UInt<1>[3] connect _array_literal_expr_1[0], UInt<1>(0h0) connect _array_literal_expr_1[1], UInt<1>(0h1) connect _array_literal_expr_1[2], UInt<1>(0h0) connect o4, {|A, B: UInt<8>, C: UInt<1>[3]|}(C, _array_literal_expr_1) @[module-XXXXXXXXXX.rs 21:1] module module2: @[module-XXXXXXXXXX-2.rs 1:1] input i: UInt<8> @[module-XXXXXXXXXX-2.rs 2:1] output o: UInt<8> @[module-XXXXXXXXXX-2.rs 3:1] wire w: UInt<8> @[module-XXXXXXXXXX-2.rs 4:1] connect w, i @[module-XXXXXXXXXX-2.rs 5:1] connect o, w @[module-XXXXXXXXXX-2.rs 6:1] ", }; } #[hdl_module(outline_generated)] pub fn check_array_repeat() where ConstUsize: KnownSize, { #[hdl] let i: UInt<8> = m.input(); #[hdl] let o: Array, N> = m.output(); connect( o, #[hdl] [i; N], ); } #[test] fn test_array_repeat() { let _n = SourceLocation::normalize_files_for_tests(); let m = check_array_repeat::<3>(); dbg!(m); #[rustfmt::skip] // work around https://github.com/rust-lang/rustfmt/issues/6161 assert_export_firrtl! { m => "/test/check_array_repeat.fir": r"FIRRTL version 3.2.0 circuit check_array_repeat: module check_array_repeat: @[module-XXXXXXXXXX.rs 1:1] input i: UInt<8> @[module-XXXXXXXXXX.rs 2:1] output o: UInt<8>[3] @[module-XXXXXXXXXX.rs 3:1] wire _array_literal_expr: UInt<8>[3] connect _array_literal_expr[0], i connect _array_literal_expr[1], i connect _array_literal_expr[2], i connect o, _array_literal_expr @[module-XXXXXXXXXX.rs 4:1] ", }; let m = check_array_repeat::<4>(); dbg!(m); #[rustfmt::skip] // work around https://github.com/rust-lang/rustfmt/issues/6161 assert_export_firrtl! { m => "/test/check_array_repeat.fir": r"FIRRTL version 3.2.0 circuit check_array_repeat: module check_array_repeat: @[module-XXXXXXXXXX.rs 1:1] input i: UInt<8> @[module-XXXXXXXXXX.rs 2:1] output o: UInt<8>[4] @[module-XXXXXXXXXX.rs 3:1] wire _array_literal_expr: UInt<8>[4] connect _array_literal_expr[0], i connect _array_literal_expr[1], i connect _array_literal_expr[2], i connect _array_literal_expr[3], i connect o, _array_literal_expr @[module-XXXXXXXXXX.rs 4:1] ", }; } #[hdl_module(outline_generated)] pub fn check_skipped_generics(v: U) where T: StaticType, ConstUsize: KnownSize, U: std::fmt::Display, { dbg!(M); #[hdl] let i: T = m.input(); #[hdl] let o: Array = m.output(); let bytes = v.to_string().as_bytes().to_expr(); #[hdl] let o2: Array> = m.output(Expr::ty(bytes)); connect( o, #[hdl] [i; N], ); connect(o2, bytes); } #[test] fn test_skipped_generics() { let _n = SourceLocation::normalize_files_for_tests(); let m = check_skipped_generics::, _, 3, 4>("Hello World!\n"); dbg!(m); #[rustfmt::skip] // work around https://github.com/rust-lang/rustfmt/issues/6161 assert_export_firrtl! { m => "/test/check_skipped_generics.fir": r"FIRRTL version 3.2.0 circuit check_skipped_generics: module check_skipped_generics: @[module-XXXXXXXXXX.rs 1:1] input i: UInt<8> @[module-XXXXXXXXXX.rs 2:1] output o: UInt<8>[3] @[module-XXXXXXXXXX.rs 3:1] output o2: UInt<8>[13] @[module-XXXXXXXXXX.rs 4:1] wire _array_literal_expr: UInt<8>[3] connect _array_literal_expr[0], i connect _array_literal_expr[1], i connect _array_literal_expr[2], i connect o, _array_literal_expr @[module-XXXXXXXXXX.rs 5:1] wire _array_literal_expr_1: UInt<8>[13] connect _array_literal_expr_1[0], UInt<8>(0h48) connect _array_literal_expr_1[1], UInt<8>(0h65) connect _array_literal_expr_1[2], UInt<8>(0h6C) connect _array_literal_expr_1[3], UInt<8>(0h6C) connect _array_literal_expr_1[4], UInt<8>(0h6F) connect _array_literal_expr_1[5], UInt<8>(0h20) connect _array_literal_expr_1[6], UInt<8>(0h57) connect _array_literal_expr_1[7], UInt<8>(0h6F) connect _array_literal_expr_1[8], UInt<8>(0h72) connect _array_literal_expr_1[9], UInt<8>(0h6C) connect _array_literal_expr_1[10], UInt<8>(0h64) connect _array_literal_expr_1[11], UInt<8>(0h21) connect _array_literal_expr_1[12], UInt<8>(0hA) connect o2, _array_literal_expr_1 @[module-XXXXXXXXXX.rs 6:1] ", }; } #[hdl_module(outline_generated)] pub fn check_partially_written() { #[hdl] let i: (UInt<8>, UInt<8>) = m.input(); #[hdl] let o: (UInt<8>, UInt<8>) = m.output(); connect(o.0, i.0); } #[test] #[should_panic(expected = "check_partially_written::o.1 is not connected to")] fn test_partially_written() { check_partially_written(); } #[hdl_module(outline_generated)] pub fn check_conditionally_written() { #[hdl] let i: UInt<8> = m.input(); #[hdl] let cond: Bool = m.input(); #[hdl] let o: UInt<8> = m.output(); #[hdl] if cond { connect(o, i); } } #[test] #[should_panic(expected = "check_conditionally_written::o is not always connected to")] fn test_conditionally_written() { check_conditionally_written(); } #[hdl_module(outline_generated)] pub fn check_written_inside_condition() { #[hdl] let i: UInt<8> = m.input(); #[hdl] let cond: Bool = m.input(); #[hdl] if cond { #[hdl] let w: UInt<8> = wire(); connect(w, i); } } #[test] fn test_written_inside_condition() { let _n = SourceLocation::normalize_files_for_tests(); let m = check_written_inside_condition(); dbg!(m); #[rustfmt::skip] // work around https://github.com/rust-lang/rustfmt/issues/6161 assert_export_firrtl! { m => "/test/check_written_inside_condition.fir": r"FIRRTL version 3.2.0 circuit check_written_inside_condition: module check_written_inside_condition: @[module-XXXXXXXXXX.rs 1:1] input i: UInt<8> @[module-XXXXXXXXXX.rs 2:1] input cond: UInt<1> @[module-XXXXXXXXXX.rs 3:1] when cond: @[module-XXXXXXXXXX.rs 4:1] wire w: UInt<8> @[module-XXXXXXXXXX.rs 5:1] connect w, i @[module-XXXXXXXXXX.rs 6:1] ", }; } #[hdl_module(outline_generated)] pub fn check_written_with_dynamic_index() { #[hdl] let i: UInt<8> = m.input(); #[hdl] let idx: UInt<8> = m.input(); #[hdl] let w: Array, 2> = wire(); connect(w[idx], i); } #[test] #[should_panic = "is not always connected to"] fn test_written_with_dynamic_index() { check_written_with_dynamic_index(); } #[hdl_module(outline_generated)] pub fn check_written_inside_both_if_else() { #[hdl] let i: UInt<8> = m.input(); #[hdl] let cond: Bool = m.input(); #[hdl] let o: UInt<8> = m.output(); #[hdl] if cond { connect(o, i); } else { connect(o, 3_hdl_u8); } } #[test] fn test_written_inside_both_if_else() { let _n = SourceLocation::normalize_files_for_tests(); let m = check_written_inside_both_if_else(); dbg!(m); #[rustfmt::skip] // work around https://github.com/rust-lang/rustfmt/issues/6161 assert_export_firrtl! { m => "/test/check_written_inside_both_if_else.fir": r"FIRRTL version 3.2.0 circuit check_written_inside_both_if_else: module check_written_inside_both_if_else: @[module-XXXXXXXXXX.rs 1:1] input i: UInt<8> @[module-XXXXXXXXXX.rs 2:1] input cond: UInt<1> @[module-XXXXXXXXXX.rs 3:1] output o: UInt<8> @[module-XXXXXXXXXX.rs 4:1] when cond: @[module-XXXXXXXXXX.rs 5:1] connect o, i @[module-XXXXXXXXXX.rs 6:1] else: connect o, UInt<8>(0h3) @[module-XXXXXXXXXX.rs 7:1] ", }; } #[hdl(outline_generated)] pub struct TestStruct { pub a: T, pub b: UInt<8>, } #[hdl(outline_generated)] pub struct TestStruct2 { pub v: UInt<8>, } #[hdl(outline_generated)] pub struct TestStruct3 {} #[hdl_module(outline_generated)] pub fn check_struct_literals() { #[hdl] let i: UInt<8> = m.input(); #[hdl] let o: TestStruct> = m.output(); #[hdl] let o2: TestStruct2 = m.output(); #[hdl] let o3: TestStruct3 = m.output(); connect( o, #[hdl] TestStruct { a: 1234u16, b: i }, ); connect( o2, #[hdl] TestStruct2 { v: i }, ); connect( o3, #[hdl] TestStruct3 {}, ); } #[test] fn test_struct_literals() { let _n = SourceLocation::normalize_files_for_tests(); let m = check_struct_literals(); dbg!(m); #[rustfmt::skip] // work around https://github.com/rust-lang/rustfmt/issues/6161 assert_export_firrtl! { m => "/test/check_struct_literals.fir": r"FIRRTL version 3.2.0 circuit check_struct_literals: type Ty0 = {a: UInt<16>, b: UInt<8>} type Ty1 = {v: UInt<8>} type Ty2 = {} module check_struct_literals: @[module-XXXXXXXXXX.rs 1:1] input i: UInt<8> @[module-XXXXXXXXXX.rs 2:1] output o: Ty0 @[module-XXXXXXXXXX.rs 3:1] output o2: Ty1 @[module-XXXXXXXXXX.rs 4:1] output o3: Ty2 @[module-XXXXXXXXXX.rs 5:1] wire _bundle_literal_expr: Ty0 connect _bundle_literal_expr.a, UInt<16>(0h4D2) connect _bundle_literal_expr.b, i connect o, _bundle_literal_expr @[module-XXXXXXXXXX.rs 6:1] wire _bundle_literal_expr_1: Ty1 connect _bundle_literal_expr_1.v, i connect o2, _bundle_literal_expr_1 @[module-XXXXXXXXXX.rs 7:1] wire _bundle_literal_expr_2: Ty2 invalidate _bundle_literal_expr_2 connect o3, _bundle_literal_expr_2 @[module-XXXXXXXXXX.rs 8:1] ", }; } #[hdl_module(outline_generated)] pub fn check_enum_literals() { #[hdl] let i: UInt<8> = m.input(); #[hdl] let o: HdlOption> = m.output(); #[hdl] let o2: TestEnum = m.output(); connect(o, HdlSome(i)); #[hdl] if i.cmp_eq(0_hdl_u8) { connect(o2, TestEnum.A()); } else if i.cmp_gt(8_hdl_u8) { connect(o2, TestEnum.B(i)); } else { connect( o2, TestEnum.C( #[hdl] [i[0], i[2], i[1]], ), ); } } #[test] fn test_enum_literals() { let _n = SourceLocation::normalize_files_for_tests(); let m = check_enum_literals(); dbg!(m); #[rustfmt::skip] // work around https://github.com/rust-lang/rustfmt/issues/6161 assert_export_firrtl! { m => options: ExportOptions { simplify_enums: None, ..ExportOptions::default() }, "/test/check_enum_literals.fir": r"FIRRTL version 3.2.0 circuit check_enum_literals: type Ty0 = {|HdlNone, HdlSome: UInt<8>|} type Ty1 = {|A, B: UInt<8>, C: UInt<1>[3]|} module check_enum_literals: @[module-XXXXXXXXXX.rs 1:1] input i: UInt<8> @[module-XXXXXXXXXX.rs 2:1] output o: Ty0 @[module-XXXXXXXXXX.rs 3:1] output o2: Ty1 @[module-XXXXXXXXXX.rs 4:1] connect o, {|HdlNone, HdlSome: UInt<8>|}(HdlSome, i) @[module-XXXXXXXXXX.rs 5:1] when eq(i, UInt<8>(0h0)): @[module-XXXXXXXXXX.rs 6:1] connect o2, {|A, B: UInt<8>, C: UInt<1>[3]|}(A) @[module-XXXXXXXXXX.rs 7:1] else when gt(i, UInt<8>(0h8)): @[module-XXXXXXXXXX.rs 8:1] connect o2, {|A, B: UInt<8>, C: UInt<1>[3]|}(B, i) @[module-XXXXXXXXXX.rs 9:1] else: wire _array_literal_expr: UInt<1>[3] connect _array_literal_expr[0], bits(i, 0, 0) connect _array_literal_expr[1], bits(i, 2, 2) connect _array_literal_expr[2], bits(i, 1, 1) connect o2, {|A, B: UInt<8>, C: UInt<1>[3]|}(C, _array_literal_expr) @[module-XXXXXXXXXX.rs 10:1] ", }; #[rustfmt::skip] // work around https://github.com/rust-lang/rustfmt/issues/6161 assert_export_firrtl! { m => options: ExportOptions { simplify_enums: Some(SimplifyEnumsKind::SimplifyToEnumsWithNoBody), ..ExportOptions::default() }, "/test/check_enum_literals.fir": r"FIRRTL version 3.2.0 circuit check_enum_literals: type Ty0 = {|HdlNone, HdlSome|} type Ty1 = {tag: Ty0, body: UInt<8>} type Ty2 = {|A, B, C|} type Ty3 = {tag: Ty2, body: UInt<8>} module check_enum_literals: @[module-XXXXXXXXXX.rs 1:1] input i: UInt<8> @[module-XXXXXXXXXX.rs 2:1] output o: Ty1 @[module-XXXXXXXXXX.rs 3:1] output o2: Ty3 @[module-XXXXXXXXXX.rs 4:1] wire _bundle_literal_expr: Ty1 connect _bundle_literal_expr.tag, {|HdlNone, HdlSome|}(HdlSome) connect _bundle_literal_expr.body, i connect o, _bundle_literal_expr @[module-XXXXXXXXXX.rs 5:1] when eq(i, UInt<8>(0h0)): @[module-XXXXXXXXXX.rs 6:1] wire _bundle_literal_expr_1: Ty3 connect _bundle_literal_expr_1.tag, {|A, B, C|}(A) connect _bundle_literal_expr_1.body, UInt<8>(0h0) connect o2, _bundle_literal_expr_1 @[module-XXXXXXXXXX.rs 7:1] else when gt(i, UInt<8>(0h8)): @[module-XXXXXXXXXX.rs 8:1] wire _bundle_literal_expr_2: Ty3 connect _bundle_literal_expr_2.tag, {|A, B, C|}(B) connect _bundle_literal_expr_2.body, i connect o2, _bundle_literal_expr_2 @[module-XXXXXXXXXX.rs 9:1] else: wire _bundle_literal_expr_3: Ty3 connect _bundle_literal_expr_3.tag, {|A, B, C|}(C) wire _array_literal_expr: UInt<1>[3] connect _array_literal_expr[0], bits(i, 0, 0) connect _array_literal_expr[1], bits(i, 2, 2) connect _array_literal_expr[2], bits(i, 1, 1) wire _cast_array_to_bits_expr: UInt<1>[3] connect _cast_array_to_bits_expr[0], _array_literal_expr[0] connect _cast_array_to_bits_expr[1], _array_literal_expr[1] connect _cast_array_to_bits_expr[2], _array_literal_expr[2] wire _cast_to_bits_expr: UInt<3> connect _cast_to_bits_expr, cat(_cast_array_to_bits_expr[2], cat(_cast_array_to_bits_expr[1], _cast_array_to_bits_expr[0])) connect _bundle_literal_expr_3.body, pad(_cast_to_bits_expr, 8) connect o2, _bundle_literal_expr_3 @[module-XXXXXXXXXX.rs 10:1] ", }; #[rustfmt::skip] // work around https://github.com/rust-lang/rustfmt/issues/6161 assert_export_firrtl! { m => options: ExportOptions { simplify_enums: Some(SimplifyEnumsKind::ReplaceWithBundleOfUInts), ..ExportOptions::default() }, "/test/check_enum_literals.fir": r"FIRRTL version 3.2.0 circuit check_enum_literals: type Ty0 = {tag: UInt<1>, body: UInt<8>} type Ty1 = {tag: UInt<2>, body: UInt<8>} module check_enum_literals: @[module-XXXXXXXXXX.rs 1:1] input i: UInt<8> @[module-XXXXXXXXXX.rs 2:1] output o: Ty0 @[module-XXXXXXXXXX.rs 3:1] output o2: Ty1 @[module-XXXXXXXXXX.rs 4:1] wire _bundle_literal_expr: Ty0 connect _bundle_literal_expr.tag, UInt<1>(0h1) connect _bundle_literal_expr.body, i connect o, _bundle_literal_expr @[module-XXXXXXXXXX.rs 5:1] when eq(i, UInt<8>(0h0)): @[module-XXXXXXXXXX.rs 6:1] wire _bundle_literal_expr_1: Ty1 connect _bundle_literal_expr_1.tag, UInt<2>(0h0) connect _bundle_literal_expr_1.body, UInt<8>(0h0) connect o2, _bundle_literal_expr_1 @[module-XXXXXXXXXX.rs 7:1] else when gt(i, UInt<8>(0h8)): @[module-XXXXXXXXXX.rs 8:1] wire _bundle_literal_expr_2: Ty1 connect _bundle_literal_expr_2.tag, UInt<2>(0h1) connect _bundle_literal_expr_2.body, i connect o2, _bundle_literal_expr_2 @[module-XXXXXXXXXX.rs 9:1] else: wire _bundle_literal_expr_3: Ty1 connect _bundle_literal_expr_3.tag, UInt<2>(0h2) wire _array_literal_expr: UInt<1>[3] connect _array_literal_expr[0], bits(i, 0, 0) connect _array_literal_expr[1], bits(i, 2, 2) connect _array_literal_expr[2], bits(i, 1, 1) wire _cast_array_to_bits_expr: UInt<1>[3] connect _cast_array_to_bits_expr[0], _array_literal_expr[0] connect _cast_array_to_bits_expr[1], _array_literal_expr[1] connect _cast_array_to_bits_expr[2], _array_literal_expr[2] wire _cast_to_bits_expr: UInt<3> connect _cast_to_bits_expr, cat(_cast_array_to_bits_expr[2], cat(_cast_array_to_bits_expr[1], _cast_array_to_bits_expr[0])) connect _bundle_literal_expr_3.body, pad(_cast_to_bits_expr, 8) connect o2, _bundle_literal_expr_3 @[module-XXXXXXXXXX.rs 10:1] ", }; #[rustfmt::skip] // work around https://github.com/rust-lang/rustfmt/issues/6161 assert_export_firrtl! { m => options: ExportOptions { simplify_enums: Some(SimplifyEnumsKind::ReplaceWithUInt), ..ExportOptions::default() }, "/test/check_enum_literals.fir": r"FIRRTL version 3.2.0 circuit check_enum_literals: type Ty0 = {tag: UInt<1>, body: UInt<8>} type Ty1 = {tag: UInt<2>, body: UInt<8>} module check_enum_literals: @[module-XXXXXXXXXX.rs 1:1] input i: UInt<8> @[module-XXXXXXXXXX.rs 2:1] output o: UInt<9> @[module-XXXXXXXXXX.rs 3:1] output o2: UInt<10> @[module-XXXXXXXXXX.rs 4:1] wire _bundle_literal_expr: Ty0 connect _bundle_literal_expr.tag, UInt<1>(0h1) connect _bundle_literal_expr.body, i wire _cast_bundle_to_bits_expr: Ty0 connect _cast_bundle_to_bits_expr.tag, _bundle_literal_expr.tag connect _cast_bundle_to_bits_expr.body, _bundle_literal_expr.body wire _cast_to_bits_expr: UInt<9> connect _cast_to_bits_expr, cat(_cast_bundle_to_bits_expr.body, _cast_bundle_to_bits_expr.tag) connect o, _cast_to_bits_expr @[module-XXXXXXXXXX.rs 5:1] when eq(i, UInt<8>(0h0)): @[module-XXXXXXXXXX.rs 6:1] wire _bundle_literal_expr_1: Ty1 connect _bundle_literal_expr_1.tag, UInt<2>(0h0) connect _bundle_literal_expr_1.body, UInt<8>(0h0) wire _cast_bundle_to_bits_expr_1: Ty1 connect _cast_bundle_to_bits_expr_1.tag, _bundle_literal_expr_1.tag connect _cast_bundle_to_bits_expr_1.body, _bundle_literal_expr_1.body wire _cast_to_bits_expr_1: UInt<10> connect _cast_to_bits_expr_1, cat(_cast_bundle_to_bits_expr_1.body, _cast_bundle_to_bits_expr_1.tag) connect o2, _cast_to_bits_expr_1 @[module-XXXXXXXXXX.rs 7:1] else when gt(i, UInt<8>(0h8)): @[module-XXXXXXXXXX.rs 8:1] wire _bundle_literal_expr_2: Ty1 connect _bundle_literal_expr_2.tag, UInt<2>(0h1) connect _bundle_literal_expr_2.body, i wire _cast_bundle_to_bits_expr_2: Ty1 connect _cast_bundle_to_bits_expr_2.tag, _bundle_literal_expr_2.tag connect _cast_bundle_to_bits_expr_2.body, _bundle_literal_expr_2.body wire _cast_to_bits_expr_2: UInt<10> connect _cast_to_bits_expr_2, cat(_cast_bundle_to_bits_expr_2.body, _cast_bundle_to_bits_expr_2.tag) connect o2, _cast_to_bits_expr_2 @[module-XXXXXXXXXX.rs 9:1] else: wire _bundle_literal_expr_3: Ty1 connect _bundle_literal_expr_3.tag, UInt<2>(0h2) wire _array_literal_expr: UInt<1>[3] connect _array_literal_expr[0], bits(i, 0, 0) connect _array_literal_expr[1], bits(i, 2, 2) connect _array_literal_expr[2], bits(i, 1, 1) wire _cast_array_to_bits_expr: UInt<1>[3] connect _cast_array_to_bits_expr[0], _array_literal_expr[0] connect _cast_array_to_bits_expr[1], _array_literal_expr[1] connect _cast_array_to_bits_expr[2], _array_literal_expr[2] wire _cast_to_bits_expr_3: UInt<3> connect _cast_to_bits_expr_3, cat(_cast_array_to_bits_expr[2], cat(_cast_array_to_bits_expr[1], _cast_array_to_bits_expr[0])) connect _bundle_literal_expr_3.body, pad(_cast_to_bits_expr_3, 8) wire _cast_bundle_to_bits_expr_3: Ty1 connect _cast_bundle_to_bits_expr_3.tag, _bundle_literal_expr_3.tag connect _cast_bundle_to_bits_expr_3.body, _bundle_literal_expr_3.body wire _cast_to_bits_expr_4: UInt<10> connect _cast_to_bits_expr_4, cat(_cast_bundle_to_bits_expr_3.body, _cast_bundle_to_bits_expr_3.tag) connect o2, _cast_to_bits_expr_4 @[module-XXXXXXXXXX.rs 10:1] ", }; } #[hdl_module(outline_generated)] pub fn check_struct_enum_match() { #[hdl] let i1: HdlOption> = m.input(); #[hdl] let i2: TestEnum = m.input(); #[hdl] let o: Array, 5> = m.output(); #[hdl] if let HdlSome(v) = i1 { connect(o[0], v); } else if let TestEnum::B(v) = i2 { connect_any(o[0], v + 2_hdl_u8); } else { connect(o[0], 23_hdl_u8); } #[hdl] match i1 { HdlSome(_) => connect(o[1], 1_hdl_u8), HdlNone => connect(o[1], 0_hdl_u8), } #[hdl] match i2 { TestEnum::A => connect(o[2], 0_hdl_u8), TestEnum::B(v) => connect(o[2], v), TestEnum::C(v) => connect_any(o[2], v[1].cast_to(UInt[1])), } #[hdl] match i2 { TestEnum::A => connect(o[3], 0_hdl_u8), TestEnum::B(_) => connect(o[3], 1_hdl_u8), TestEnum::C(..) => connect(o[3], 2_hdl_u8), } #[hdl] match i2 { TestEnum::B(_) => connect(o[4], 1_hdl_u8), TestEnum::C(v) => connect_any(o[4], v[2].cast_to(UInt[1])), _ => connect(o[4], 0_hdl_u8), } } #[test] fn test_struct_enum_match() { let _n = SourceLocation::normalize_files_for_tests(); let m = check_struct_enum_match(); dbg!(m); #[rustfmt::skip] // work around https://github.com/rust-lang/rustfmt/issues/6161 assert_export_firrtl! { m => options: ExportOptions { simplify_enums: None, ..ExportOptions::default() }, "/test/check_struct_enum_match.fir": r"FIRRTL version 3.2.0 circuit check_struct_enum_match: type Ty0 = {|HdlNone, HdlSome: UInt<8>|} type Ty1 = {|A, B: UInt<8>, C: UInt<1>[3]|} module check_struct_enum_match: @[module-XXXXXXXXXX.rs 1:1] input i1: Ty0 @[module-XXXXXXXXXX.rs 2:1] input i2: Ty1 @[module-XXXXXXXXXX.rs 3:1] output o: UInt<8>[5] @[module-XXXXXXXXXX.rs 4:1] match i1: @[module-XXXXXXXXXX.rs 5:1] HdlNone: match i2: @[module-XXXXXXXXXX.rs 6:1] A: connect o[0], UInt<8>(0h17) @[module-XXXXXXXXXX.rs 7:1] B(_match_arm_value): ; connect different types: ; lhs: UInt<8> ; rhs: UInt<9> connect o[0], add(_match_arm_value, UInt<8>(0h2)) @[module-XXXXXXXXXX.rs 8:1] C(_match_arm_value_1): connect o[0], UInt<8>(0h17) @[module-XXXXXXXXXX.rs 7:1] HdlSome(_match_arm_value_2): connect o[0], _match_arm_value_2 @[module-XXXXXXXXXX.rs 9:1] match i1: @[module-XXXXXXXXXX.rs 10:1] HdlNone: connect o[1], UInt<8>(0h0) @[module-XXXXXXXXXX.rs 11:1] HdlSome(_match_arm_value_3): connect o[1], UInt<8>(0h1) @[module-XXXXXXXXXX.rs 12:1] match i2: @[module-XXXXXXXXXX.rs 13:1] A: connect o[2], UInt<8>(0h0) @[module-XXXXXXXXXX.rs 14:1] B(_match_arm_value_4): connect o[2], _match_arm_value_4 @[module-XXXXXXXXXX.rs 15:1] C(_match_arm_value_5): ; connect different types: ; lhs: UInt<8> ; rhs: UInt<1> connect o[2], _match_arm_value_5[1] @[module-XXXXXXXXXX.rs 16:1] match i2: @[module-XXXXXXXXXX.rs 17:1] A: connect o[3], UInt<8>(0h0) @[module-XXXXXXXXXX.rs 18:1] B(_match_arm_value_6): connect o[3], UInt<8>(0h1) @[module-XXXXXXXXXX.rs 19:1] C(_match_arm_value_7): connect o[3], UInt<8>(0h2) @[module-XXXXXXXXXX.rs 20:1] match i2: @[module-XXXXXXXXXX.rs 21:1] A: connect o[4], UInt<8>(0h0) @[module-XXXXXXXXXX.rs 22:1] B(_match_arm_value_8): connect o[4], UInt<8>(0h1) @[module-XXXXXXXXXX.rs 23:1] C(_match_arm_value_9): ; connect different types: ; lhs: UInt<8> ; rhs: UInt<1> connect o[4], _match_arm_value_9[2] @[module-XXXXXXXXXX.rs 24:1] ", }; #[rustfmt::skip] // work around https://github.com/rust-lang/rustfmt/issues/6161 assert_export_firrtl! { m => options: ExportOptions { simplify_enums: Some(SimplifyEnumsKind::SimplifyToEnumsWithNoBody), ..ExportOptions::default() }, "/test/check_struct_enum_match.fir": r"FIRRTL version 3.2.0 circuit check_struct_enum_match: type Ty0 = {|HdlNone, HdlSome|} type Ty1 = {tag: Ty0, body: UInt<8>} type Ty2 = {|A, B, C|} type Ty3 = {tag: Ty2, body: UInt<8>} module check_struct_enum_match: @[module-XXXXXXXXXX.rs 1:1] input i1: Ty1 @[module-XXXXXXXXXX.rs 2:1] input i2: Ty3 @[module-XXXXXXXXXX.rs 3:1] output o: UInt<8>[5] @[module-XXXXXXXXXX.rs 4:1] match i1.tag: @[module-XXXXXXXXXX.rs 5:1] HdlNone: match i2.tag: @[module-XXXXXXXXXX.rs 6:1] A: connect o[0], UInt<8>(0h17) @[module-XXXXXXXXXX.rs 7:1] B: ; connect different types: ; lhs: UInt<8> ; rhs: UInt<9> connect o[0], add(bits(i2.body, 7, 0), UInt<8>(0h2)) @[module-XXXXXXXXXX.rs 8:1] C: connect o[0], UInt<8>(0h17) @[module-XXXXXXXXXX.rs 7:1] HdlSome: connect o[0], bits(i1.body, 7, 0) @[module-XXXXXXXXXX.rs 9:1] match i1.tag: @[module-XXXXXXXXXX.rs 10:1] HdlNone: connect o[1], UInt<8>(0h0) @[module-XXXXXXXXXX.rs 11:1] HdlSome: connect o[1], UInt<8>(0h1) @[module-XXXXXXXXXX.rs 12:1] match i2.tag: @[module-XXXXXXXXXX.rs 13:1] A: connect o[2], UInt<8>(0h0) @[module-XXXXXXXXXX.rs 14:1] B: connect o[2], bits(i2.body, 7, 0) @[module-XXXXXXXXXX.rs 15:1] C: wire _cast_bits_to_array_expr: UInt<1>[3] wire _cast_bits_to_array_expr_flattened: UInt<1>[3] connect _cast_bits_to_array_expr_flattened[0], bits(bits(i2.body, 2, 0), 0, 0) connect _cast_bits_to_array_expr[0], _cast_bits_to_array_expr_flattened[0] connect _cast_bits_to_array_expr_flattened[1], bits(bits(i2.body, 2, 0), 1, 1) connect _cast_bits_to_array_expr[1], _cast_bits_to_array_expr_flattened[1] connect _cast_bits_to_array_expr_flattened[2], bits(bits(i2.body, 2, 0), 2, 2) connect _cast_bits_to_array_expr[2], _cast_bits_to_array_expr_flattened[2] ; connect different types: ; lhs: UInt<8> ; rhs: UInt<1> connect o[2], _cast_bits_to_array_expr[1] @[module-XXXXXXXXXX.rs 16:1] match i2.tag: @[module-XXXXXXXXXX.rs 17:1] A: connect o[3], UInt<8>(0h0) @[module-XXXXXXXXXX.rs 18:1] B: connect o[3], UInt<8>(0h1) @[module-XXXXXXXXXX.rs 19:1] C: connect o[3], UInt<8>(0h2) @[module-XXXXXXXXXX.rs 20:1] match i2.tag: @[module-XXXXXXXXXX.rs 21:1] A: connect o[4], UInt<8>(0h0) @[module-XXXXXXXXXX.rs 22:1] B: connect o[4], UInt<8>(0h1) @[module-XXXXXXXXXX.rs 23:1] C: wire _cast_bits_to_array_expr_1: UInt<1>[3] wire _cast_bits_to_array_expr_flattened_1: UInt<1>[3] connect _cast_bits_to_array_expr_flattened_1[0], bits(bits(i2.body, 2, 0), 0, 0) connect _cast_bits_to_array_expr_1[0], _cast_bits_to_array_expr_flattened_1[0] connect _cast_bits_to_array_expr_flattened_1[1], bits(bits(i2.body, 2, 0), 1, 1) connect _cast_bits_to_array_expr_1[1], _cast_bits_to_array_expr_flattened_1[1] connect _cast_bits_to_array_expr_flattened_1[2], bits(bits(i2.body, 2, 0), 2, 2) connect _cast_bits_to_array_expr_1[2], _cast_bits_to_array_expr_flattened_1[2] ; connect different types: ; lhs: UInt<8> ; rhs: UInt<1> connect o[4], _cast_bits_to_array_expr_1[2] @[module-XXXXXXXXXX.rs 24:1] ", }; #[rustfmt::skip] // work around https://github.com/rust-lang/rustfmt/issues/6161 assert_export_firrtl! { m => options: ExportOptions { simplify_enums: Some(SimplifyEnumsKind::ReplaceWithBundleOfUInts), ..ExportOptions::default() }, "/test/check_struct_enum_match.fir": r"FIRRTL version 3.2.0 circuit check_struct_enum_match: type Ty0 = {tag: UInt<1>, body: UInt<8>} type Ty1 = {tag: UInt<2>, body: UInt<8>} module check_struct_enum_match: @[module-XXXXXXXXXX.rs 1:1] input i1: Ty0 @[module-XXXXXXXXXX.rs 2:1] input i2: Ty1 @[module-XXXXXXXXXX.rs 3:1] output o: UInt<8>[5] @[module-XXXXXXXXXX.rs 4:1] when eq(i1.tag, UInt<1>(0h0)): @[module-XXXXXXXXXX.rs 5:1] when eq(i2.tag, UInt<2>(0h0)): @[module-XXXXXXXXXX.rs 6:1] connect o[0], UInt<8>(0h17) @[module-XXXXXXXXXX.rs 7:1] else when eq(i2.tag, UInt<2>(0h1)): @[module-XXXXXXXXXX.rs 6:1] ; connect different types: ; lhs: UInt<8> ; rhs: UInt<9> connect o[0], add(bits(i2.body, 7, 0), UInt<8>(0h2)) @[module-XXXXXXXXXX.rs 8:1] else: connect o[0], UInt<8>(0h17) @[module-XXXXXXXXXX.rs 7:1] else: connect o[0], bits(i1.body, 7, 0) @[module-XXXXXXXXXX.rs 9:1] when eq(i1.tag, UInt<1>(0h0)): @[module-XXXXXXXXXX.rs 10:1] connect o[1], UInt<8>(0h0) @[module-XXXXXXXXXX.rs 11:1] else: connect o[1], UInt<8>(0h1) @[module-XXXXXXXXXX.rs 12:1] when eq(i2.tag, UInt<2>(0h0)): @[module-XXXXXXXXXX.rs 13:1] connect o[2], UInt<8>(0h0) @[module-XXXXXXXXXX.rs 14:1] else when eq(i2.tag, UInt<2>(0h1)): @[module-XXXXXXXXXX.rs 13:1] connect o[2], bits(i2.body, 7, 0) @[module-XXXXXXXXXX.rs 15:1] else: wire _cast_bits_to_array_expr: UInt<1>[3] wire _cast_bits_to_array_expr_flattened: UInt<1>[3] connect _cast_bits_to_array_expr_flattened[0], bits(bits(i2.body, 2, 0), 0, 0) connect _cast_bits_to_array_expr[0], _cast_bits_to_array_expr_flattened[0] connect _cast_bits_to_array_expr_flattened[1], bits(bits(i2.body, 2, 0), 1, 1) connect _cast_bits_to_array_expr[1], _cast_bits_to_array_expr_flattened[1] connect _cast_bits_to_array_expr_flattened[2], bits(bits(i2.body, 2, 0), 2, 2) connect _cast_bits_to_array_expr[2], _cast_bits_to_array_expr_flattened[2] ; connect different types: ; lhs: UInt<8> ; rhs: UInt<1> connect o[2], _cast_bits_to_array_expr[1] @[module-XXXXXXXXXX.rs 16:1] when eq(i2.tag, UInt<2>(0h0)): @[module-XXXXXXXXXX.rs 17:1] connect o[3], UInt<8>(0h0) @[module-XXXXXXXXXX.rs 18:1] else when eq(i2.tag, UInt<2>(0h1)): @[module-XXXXXXXXXX.rs 17:1] connect o[3], UInt<8>(0h1) @[module-XXXXXXXXXX.rs 19:1] else: connect o[3], UInt<8>(0h2) @[module-XXXXXXXXXX.rs 20:1] when eq(i2.tag, UInt<2>(0h0)): @[module-XXXXXXXXXX.rs 21:1] connect o[4], UInt<8>(0h0) @[module-XXXXXXXXXX.rs 22:1] else when eq(i2.tag, UInt<2>(0h1)): @[module-XXXXXXXXXX.rs 21:1] connect o[4], UInt<8>(0h1) @[module-XXXXXXXXXX.rs 23:1] else: wire _cast_bits_to_array_expr_1: UInt<1>[3] wire _cast_bits_to_array_expr_flattened_1: UInt<1>[3] connect _cast_bits_to_array_expr_flattened_1[0], bits(bits(i2.body, 2, 0), 0, 0) connect _cast_bits_to_array_expr_1[0], _cast_bits_to_array_expr_flattened_1[0] connect _cast_bits_to_array_expr_flattened_1[1], bits(bits(i2.body, 2, 0), 1, 1) connect _cast_bits_to_array_expr_1[1], _cast_bits_to_array_expr_flattened_1[1] connect _cast_bits_to_array_expr_flattened_1[2], bits(bits(i2.body, 2, 0), 2, 2) connect _cast_bits_to_array_expr_1[2], _cast_bits_to_array_expr_flattened_1[2] ; connect different types: ; lhs: UInt<8> ; rhs: UInt<1> connect o[4], _cast_bits_to_array_expr_1[2] @[module-XXXXXXXXXX.rs 24:1] ", }; #[rustfmt::skip] // work around https://github.com/rust-lang/rustfmt/issues/6161 assert_export_firrtl! { m => options: ExportOptions { simplify_enums: Some(SimplifyEnumsKind::ReplaceWithUInt), ..ExportOptions::default() }, "/test/check_struct_enum_match.fir": r"FIRRTL version 3.2.0 circuit check_struct_enum_match: module check_struct_enum_match: @[module-XXXXXXXXXX.rs 1:1] input i1: UInt<9> @[module-XXXXXXXXXX.rs 2:1] input i2: UInt<10> @[module-XXXXXXXXXX.rs 3:1] output o: UInt<8>[5] @[module-XXXXXXXXXX.rs 4:1] when eq(bits(i1, 0, 0), UInt<1>(0h0)): @[module-XXXXXXXXXX.rs 5:1] when eq(bits(i2, 1, 0), UInt<2>(0h0)): @[module-XXXXXXXXXX.rs 6:1] connect o[0], UInt<8>(0h17) @[module-XXXXXXXXXX.rs 7:1] else when eq(bits(i2, 1, 0), UInt<2>(0h1)): @[module-XXXXXXXXXX.rs 6:1] ; connect different types: ; lhs: UInt<8> ; rhs: UInt<9> connect o[0], add(bits(bits(i2, 9, 2), 7, 0), UInt<8>(0h2)) @[module-XXXXXXXXXX.rs 8:1] else: connect o[0], UInt<8>(0h17) @[module-XXXXXXXXXX.rs 7:1] else: connect o[0], bits(bits(i1, 8, 1), 7, 0) @[module-XXXXXXXXXX.rs 9:1] when eq(bits(i1, 0, 0), UInt<1>(0h0)): @[module-XXXXXXXXXX.rs 10:1] connect o[1], UInt<8>(0h0) @[module-XXXXXXXXXX.rs 11:1] else: connect o[1], UInt<8>(0h1) @[module-XXXXXXXXXX.rs 12:1] when eq(bits(i2, 1, 0), UInt<2>(0h0)): @[module-XXXXXXXXXX.rs 13:1] connect o[2], UInt<8>(0h0) @[module-XXXXXXXXXX.rs 14:1] else when eq(bits(i2, 1, 0), UInt<2>(0h1)): @[module-XXXXXXXXXX.rs 13:1] connect o[2], bits(bits(i2, 9, 2), 7, 0) @[module-XXXXXXXXXX.rs 15:1] else: wire _cast_bits_to_array_expr: UInt<1>[3] wire _cast_bits_to_array_expr_flattened: UInt<1>[3] connect _cast_bits_to_array_expr_flattened[0], bits(bits(bits(i2, 9, 2), 2, 0), 0, 0) connect _cast_bits_to_array_expr[0], _cast_bits_to_array_expr_flattened[0] connect _cast_bits_to_array_expr_flattened[1], bits(bits(bits(i2, 9, 2), 2, 0), 1, 1) connect _cast_bits_to_array_expr[1], _cast_bits_to_array_expr_flattened[1] connect _cast_bits_to_array_expr_flattened[2], bits(bits(bits(i2, 9, 2), 2, 0), 2, 2) connect _cast_bits_to_array_expr[2], _cast_bits_to_array_expr_flattened[2] ; connect different types: ; lhs: UInt<8> ; rhs: UInt<1> connect o[2], _cast_bits_to_array_expr[1] @[module-XXXXXXXXXX.rs 16:1] when eq(bits(i2, 1, 0), UInt<2>(0h0)): @[module-XXXXXXXXXX.rs 17:1] connect o[3], UInt<8>(0h0) @[module-XXXXXXXXXX.rs 18:1] else when eq(bits(i2, 1, 0), UInt<2>(0h1)): @[module-XXXXXXXXXX.rs 17:1] connect o[3], UInt<8>(0h1) @[module-XXXXXXXXXX.rs 19:1] else: connect o[3], UInt<8>(0h2) @[module-XXXXXXXXXX.rs 20:1] when eq(bits(i2, 1, 0), UInt<2>(0h0)): @[module-XXXXXXXXXX.rs 21:1] connect o[4], UInt<8>(0h0) @[module-XXXXXXXXXX.rs 22:1] else when eq(bits(i2, 1, 0), UInt<2>(0h1)): @[module-XXXXXXXXXX.rs 21:1] connect o[4], UInt<8>(0h1) @[module-XXXXXXXXXX.rs 23:1] else: wire _cast_bits_to_array_expr_1: UInt<1>[3] wire _cast_bits_to_array_expr_flattened_1: UInt<1>[3] connect _cast_bits_to_array_expr_flattened_1[0], bits(bits(bits(i2, 9, 2), 2, 0), 0, 0) connect _cast_bits_to_array_expr_1[0], _cast_bits_to_array_expr_flattened_1[0] connect _cast_bits_to_array_expr_flattened_1[1], bits(bits(bits(i2, 9, 2), 2, 0), 1, 1) connect _cast_bits_to_array_expr_1[1], _cast_bits_to_array_expr_flattened_1[1] connect _cast_bits_to_array_expr_flattened_1[2], bits(bits(bits(i2, 9, 2), 2, 0), 2, 2) connect _cast_bits_to_array_expr_1[2], _cast_bits_to_array_expr_flattened_1[2] ; connect different types: ; lhs: UInt<8> ; rhs: UInt<1> connect o[4], _cast_bits_to_array_expr_1[2] @[module-XXXXXXXXXX.rs 24:1] ", }; } #[hdl_module(outline_generated)] pub fn check_extern_module() { #[hdl] let i1: UInt<8> = m.input(); #[hdl] let i2: Clock = m.input(); #[hdl] let o: SInt<12> = m.output(); #[hdl_module(extern)] fn extern_module() { #[hdl] let i1: UInt<8> = m.input(); #[hdl] let i2: Clock = m.input(); #[hdl] let o: SInt<12> = m.output(); m.verilog_name("verilog_module"); m.parameter_int("int_param", 0xFEDCBA9876543210u64 as i64); m.parameter_str("str_param", "foo\nbar\nš„ž"); m.parameter_raw_verilog("raw_param", "12'hxzx"); } #[hdl] let submodule = instance(extern_module()); connect(submodule.i1, i1); connect(submodule.i2, i2); connect(o, submodule.o); } #[test] fn test_extern_module() { let _n = SourceLocation::normalize_files_for_tests(); let m = check_extern_module(); dbg!(m); #[rustfmt::skip] // work around https://github.com/rust-lang/rustfmt/issues/6161 assert_export_firrtl! { m => "/test/check_extern_module.fir": r#"FIRRTL version 3.2.0 circuit check_extern_module: type Ty0 = {flip i1: UInt<8>, flip i2: Clock, o: SInt<12>} module check_extern_module: @[module-XXXXXXXXXX.rs 1:1] input i1: UInt<8> @[module-XXXXXXXXXX.rs 2:1] input i2: Clock @[module-XXXXXXXXXX.rs 3:1] output o: SInt<12> @[module-XXXXXXXXXX.rs 4:1] inst submodule of extern_module @[module-XXXXXXXXXX.rs 9:1] connect submodule.i1, i1 @[module-XXXXXXXXXX.rs 10:1] connect submodule.i2, i2 @[module-XXXXXXXXXX.rs 11:1] connect o, submodule.o @[module-XXXXXXXXXX.rs 12:1] extmodule extern_module: @[module-XXXXXXXXXX.rs 5:1] input i1: UInt<8> @[module-XXXXXXXXXX.rs 6:1] input i2: Clock @[module-XXXXXXXXXX.rs 7:1] output o: SInt<12> @[module-XXXXXXXXXX.rs 8:1] defname = verilog_module parameter int_param = -81985529216486896 parameter str_param = "foo\nbar\n\F0\9D\84\9E" parameter raw_param = '12\'hxzx' "#, }; } #[hdl_module(outline_generated)] pub fn check_memory() { #[hdl] let raddr: UInt<8> = m.input(); #[hdl] let rdata: UInt<8> = m.output(); #[hdl] let waddr: UInt<8> = m.input(); #[hdl] let wdata: UInt<8> = m.input(); #[hdl] let clk: Clock = m.input(); #[hdl] let mut mem = memory(); mem.depth(0x100); let read_port = mem.new_read_port(); connect_any(read_port.addr, raddr); connect(read_port.en, true); connect(read_port.clk, clk); connect(rdata, read_port.data); let write_port = mem.new_write_port(); connect_any(write_port.addr, waddr); connect(write_port.en, true); connect(write_port.clk, clk); connect(write_port.data, wdata); connect(write_port.mask, true); } #[test] fn test_memory() { let _n = SourceLocation::normalize_files_for_tests(); let m = check_memory(); dbg!(m); #[rustfmt::skip] // work around https://github.com/rust-lang/rustfmt/issues/6161 assert_export_firrtl! { m => "/test/check_memory.fir": r"FIRRTL version 3.2.0 circuit check_memory: type Ty0 = {addr: UInt<8>, en: UInt<1>, clk: Clock, flip data: UInt<8>} type Ty1 = {addr: UInt<8>, en: UInt<1>, clk: Clock, data: UInt<8>, mask: UInt<1>} module check_memory: @[module-XXXXXXXXXX.rs 1:1] input raddr: UInt<8> @[module-XXXXXXXXXX.rs 2:1] output rdata: UInt<8> @[module-XXXXXXXXXX.rs 3:1] input waddr: UInt<8> @[module-XXXXXXXXXX.rs 4:1] input wdata: UInt<8> @[module-XXXXXXXXXX.rs 5:1] input clk: Clock @[module-XXXXXXXXXX.rs 6:1] mem `mem`: @[module-XXXXXXXXXX.rs 7:1] data-type => UInt<8> depth => 256 read-latency => 0 write-latency => 1 read-under-write => old reader => r0 writer => w1 connect `mem`.r0.addr, raddr @[module-XXXXXXXXXX.rs 9:1] connect `mem`.r0.en, UInt<1>(0h1) @[module-XXXXXXXXXX.rs 10:1] connect `mem`.r0.clk, clk @[module-XXXXXXXXXX.rs 11:1] connect rdata, `mem`.r0.data @[module-XXXXXXXXXX.rs 12:1] connect `mem`.w1.addr, waddr @[module-XXXXXXXXXX.rs 14:1] connect `mem`.w1.en, UInt<1>(0h1) @[module-XXXXXXXXXX.rs 15:1] connect `mem`.w1.clk, clk @[module-XXXXXXXXXX.rs 16:1] connect `mem`.w1.data, wdata @[module-XXXXXXXXXX.rs 17:1] connect `mem`.w1.mask, UInt<1>(0h1) @[module-XXXXXXXXXX.rs 18:1] ", }; } #[hdl_module(outline_generated)] pub fn check_memory_init() { #[hdl] let clk: Clock = m.input(); #[hdl] let raddr1: UInt<8> = m.input(); #[hdl] let rdata1: UInt<8> = m.output(); #[hdl] let waddr1: UInt<8> = m.input(); #[hdl] let wdata1: UInt<8> = m.input(); let mem_init1 = Vec::from_iter((0..0x100).map(|i| (i * i) as u8)); #[hdl] let mut mem1 = memory_with_init(mem_init1); let read_port1 = mem1.new_read_port(); connect_any(read_port1.addr, raddr1); connect(read_port1.en, true); connect(read_port1.clk, clk); connect(rdata1, read_port1.data); let write_port1 = mem1.new_write_port(); connect_any(write_port1.addr, waddr1); connect(write_port1.en, true); connect(write_port1.clk, clk); connect(write_port1.data, wdata1); connect(write_port1.mask, true); #[hdl] let raddr2: UInt<4> = m.input(); #[hdl] let rdata2: UInt<31> = m.output(); #[hdl] let waddr2: UInt<4> = m.input(); #[hdl] let wdata2: UInt<31> = m.input(); let mem_init2 = Vec::from_iter((0..0x10u32).map(|i| (i * i * i).cast_to_static())); #[hdl] let mut mem2 = memory_with_init(mem_init2); let read_port2 = mem2.new_read_port(); connect_any(read_port2.addr, raddr2); connect(read_port2.en, true); connect(read_port2.clk, clk); connect(rdata2, read_port2.data); let write_port2 = mem2.new_write_port(); connect_any(write_port2.addr, waddr2); connect(write_port2.en, true); connect(write_port2.clk, clk); connect(write_port2.data, wdata2); connect(write_port2.mask, true); } #[test] fn test_memory_init() { let _n = SourceLocation::normalize_files_for_tests(); let m = check_memory_init(); dbg!(m); #[rustfmt::skip] // work around https://github.com/rust-lang/rustfmt/issues/6161 assert_export_firrtl! { m => "/test/check_memory_init.fir": r#"FIRRTL version 3.2.0 circuit check_memory_init: %[[ { "class": "firrtl.annotations.MemoryFileInlineAnnotation", "filename": "/test/check_memory_init/mem1.mem", "hexOrBinary": "h", "target": "~check_memory_init|check_memory_init>mem1" }, { "class": "firrtl.annotations.MemoryFileInlineAnnotation", "filename": "/test/check_memory_init/mem2.mem", "hexOrBinary": "b", "target": "~check_memory_init|check_memory_init>mem2" } ]] type Ty0 = {addr: UInt<8>, en: UInt<1>, clk: Clock, flip data: UInt<8>} type Ty1 = {addr: UInt<8>, en: UInt<1>, clk: Clock, data: UInt<8>, mask: UInt<1>} type Ty2 = {addr: UInt<4>, en: UInt<1>, clk: Clock, flip data: UInt<31>} type Ty3 = {addr: UInt<4>, en: UInt<1>, clk: Clock, data: UInt<31>, mask: UInt<1>} module check_memory_init: @[module-XXXXXXXXXX.rs 1:1] input clk: Clock @[module-XXXXXXXXXX.rs 2:1] input raddr1: UInt<8> @[module-XXXXXXXXXX.rs 3:1] output rdata1: UInt<8> @[module-XXXXXXXXXX.rs 4:1] input waddr1: UInt<8> @[module-XXXXXXXXXX.rs 5:1] input wdata1: UInt<8> @[module-XXXXXXXXXX.rs 6:1] input raddr2: UInt<4> @[module-XXXXXXXXXX.rs 19:1] output rdata2: UInt<31> @[module-XXXXXXXXXX.rs 20:1] input waddr2: UInt<4> @[module-XXXXXXXXXX.rs 21:1] input wdata2: UInt<31> @[module-XXXXXXXXXX.rs 22:1] mem mem1: @[module-XXXXXXXXXX.rs 7:1] data-type => UInt<8> depth => 256 read-latency => 0 write-latency => 1 read-under-write => old reader => r0 writer => w1 mem mem2: @[module-XXXXXXXXXX.rs 23:1] data-type => UInt<31> depth => 16 read-latency => 0 write-latency => 1 read-under-write => old reader => r0 writer => w1 connect mem1.r0.addr, raddr1 @[module-XXXXXXXXXX.rs 9:1] connect mem1.r0.en, UInt<1>(0h1) @[module-XXXXXXXXXX.rs 10:1] connect mem1.r0.clk, clk @[module-XXXXXXXXXX.rs 11:1] connect rdata1, mem1.r0.data @[module-XXXXXXXXXX.rs 12:1] connect mem1.w1.addr, waddr1 @[module-XXXXXXXXXX.rs 14:1] connect mem1.w1.en, UInt<1>(0h1) @[module-XXXXXXXXXX.rs 15:1] connect mem1.w1.clk, clk @[module-XXXXXXXXXX.rs 16:1] connect mem1.w1.data, wdata1 @[module-XXXXXXXXXX.rs 17:1] connect mem1.w1.mask, UInt<1>(0h1) @[module-XXXXXXXXXX.rs 18:1] connect mem2.r0.addr, raddr2 @[module-XXXXXXXXXX.rs 25:1] connect mem2.r0.en, UInt<1>(0h1) @[module-XXXXXXXXXX.rs 26:1] connect mem2.r0.clk, clk @[module-XXXXXXXXXX.rs 27:1] connect rdata2, mem2.r0.data @[module-XXXXXXXXXX.rs 28:1] connect mem2.w1.addr, waddr2 @[module-XXXXXXXXXX.rs 30:1] connect mem2.w1.en, UInt<1>(0h1) @[module-XXXXXXXXXX.rs 31:1] connect mem2.w1.clk, clk @[module-XXXXXXXXXX.rs 32:1] connect mem2.w1.data, wdata2 @[module-XXXXXXXXXX.rs 33:1] connect mem2.w1.mask, UInt<1>(0h1) @[module-XXXXXXXXXX.rs 34:1] "#, "/test/check_memory_init/mem1.mem": r"00 01 04 09 10 19 24 31 40 51 64 79 90 a9 c4 e1 00 21 44 69 90 b9 e4 11 40 71 a4 d9 10 49 84 c1 00 41 84 c9 10 59 a4 f1 40 91 e4 39 90 e9 44 a1 00 61 c4 29 90 f9 64 d1 40 b1 24 99 10 89 04 81 00 81 04 89 10 99 24 b1 40 d1 64 f9 90 29 c4 61 00 a1 44 e9 90 39 e4 91 40 f1 a4 59 10 c9 84 41 00 c1 84 49 10 d9 a4 71 40 11 e4 b9 90 69 44 21 00 e1 c4 a9 90 79 64 51 40 31 24 19 10 09 04 01 00 01 04 09 10 19 24 31 40 51 64 79 90 a9 c4 e1 00 21 44 69 90 b9 e4 11 40 71 a4 d9 10 49 84 c1 00 41 84 c9 10 59 a4 f1 40 91 e4 39 90 e9 44 a1 00 61 c4 29 90 f9 64 d1 40 b1 24 99 10 89 04 81 00 81 04 89 10 99 24 b1 40 d1 64 f9 90 29 c4 61 00 a1 44 e9 90 39 e4 91 40 f1 a4 59 10 c9 84 41 00 c1 84 49 10 d9 a4 71 40 11 e4 b9 90 69 44 21 00 e1 c4 a9 90 79 64 51 40 31 24 19 10 09 04 01 ", "/test/check_memory_init/mem2.mem": r"0000000000000000000000000000000 0000000000000000000000000000001 0000000000000000000000000001000 0000000000000000000000000011011 0000000000000000000000001000000 0000000000000000000000001111101 0000000000000000000000011011000 0000000000000000000000101010111 0000000000000000000001000000000 0000000000000000000001011011001 0000000000000000000001111101000 0000000000000000000010100110011 0000000000000000000011011000000 0000000000000000000100010010101 0000000000000000000101010111000 0000000000000000000110100101111 ", }; } #[hdl_module(outline_generated)] pub fn check_memory_of_array() { #[hdl] let raddr: UInt<4> = m.input(); #[hdl] let rdata: Array, 3> = m.output(); #[hdl] let waddr: UInt<4> = m.input(); #[hdl] let wdata: Array, 3> = m.input(); #[hdl] let wmask: Array = m.input(); #[hdl] let clk: Clock = m.input(); let mem_init = Vec::from_iter((0..0x10u8).map(|i| [i, i * i, (i * i).wrapping_mul(i)])); #[hdl] let mut mem = memory_with_init(mem_init); let read_port = mem.new_read_port(); connect_any(read_port.addr, raddr); connect(read_port.en, true); connect(read_port.clk, clk); connect(rdata, read_port.data); let write_port = mem.new_write_port(); connect_any(write_port.addr, waddr); connect(write_port.en, true); connect(write_port.clk, clk); connect(write_port.data, wdata); connect(write_port.mask, wmask); } #[test] fn test_memory_of_array() { let _n = SourceLocation::normalize_files_for_tests(); let m = check_memory_of_array(); dbg!(m); #[rustfmt::skip] // work around https://github.com/rust-lang/rustfmt/issues/6161 assert_export_firrtl! { m => "/test/check_memory_of_array.fir": r#"FIRRTL version 3.2.0 circuit check_memory_of_array: %[[ { "class": "firrtl.annotations.MemoryFileInlineAnnotation", "filename": "/test/check_memory_of_array/mem.mem", "hexOrBinary": "h", "target": "~check_memory_of_array|check_memory_of_array>mem" } ]] type Ty0 = {addr: UInt<4>, en: UInt<1>, clk: Clock, flip data: UInt<8>[3]} type Ty1 = {addr: UInt<4>, en: UInt<1>, clk: Clock, data: UInt<8>[3], mask: UInt<1>[3]} module check_memory_of_array: @[module-XXXXXXXXXX.rs 1:1] input raddr: UInt<4> @[module-XXXXXXXXXX.rs 2:1] output rdata: UInt<8>[3] @[module-XXXXXXXXXX.rs 3:1] input waddr: UInt<4> @[module-XXXXXXXXXX.rs 4:1] input wdata: UInt<8>[3] @[module-XXXXXXXXXX.rs 5:1] input wmask: UInt<1>[3] @[module-XXXXXXXXXX.rs 6:1] input clk: Clock @[module-XXXXXXXXXX.rs 7:1] mem `mem`: @[module-XXXXXXXXXX.rs 8:1] data-type => UInt<8>[3] depth => 16 read-latency => 0 write-latency => 1 read-under-write => old reader => r0 writer => w1 connect `mem`.r0.addr, raddr @[module-XXXXXXXXXX.rs 10:1] connect `mem`.r0.en, UInt<1>(0h1) @[module-XXXXXXXXXX.rs 11:1] connect `mem`.r0.clk, clk @[module-XXXXXXXXXX.rs 12:1] connect rdata, `mem`.r0.data @[module-XXXXXXXXXX.rs 13:1] connect `mem`.w1.addr, waddr @[module-XXXXXXXXXX.rs 15:1] connect `mem`.w1.en, UInt<1>(0h1) @[module-XXXXXXXXXX.rs 16:1] connect `mem`.w1.clk, clk @[module-XXXXXXXXXX.rs 17:1] connect `mem`.w1.data, wdata @[module-XXXXXXXXXX.rs 18:1] connect `mem`.w1.mask, wmask @[module-XXXXXXXXXX.rs 19:1] "#, "/test/check_memory_of_array/mem.mem": r"000000 010101 080402 1b0903 401004 7d1905 d82406 573107 004008 d95109 e8640a 33790b c0900c 95a90d b8c40e 2fe10f ", }; } #[hdl_module(outline_generated)] pub fn check_memory_of_arrays() { #[hdl] let raddr: UInt<4> = m.input(); #[hdl] let rdata: Array, 2>, 3> = m.output(); #[hdl] let waddr: UInt<4> = m.input(); #[hdl] let wdata: Array, 2>, 3> = m.input(); #[hdl] let wmask: Array, 3> = m.input(); #[hdl] let clk: Clock = m.input(); let mem_init = Vec::from_iter((0..0x10u8).map(|i| { [ [i, i * i], [(i * i).wrapping_mul(2), (i * i).wrapping_mul(3)], [(i * i).wrapping_mul(i), i * 2], ] })); #[hdl] let mut mem = memory_with_init(mem_init); let read_port = mem.new_read_port(); connect_any(read_port.addr, raddr); connect(read_port.en, true); connect(read_port.clk, clk); connect(rdata, read_port.data); let write_port = mem.new_write_port(); connect_any(write_port.addr, waddr); connect(write_port.en, true); connect(write_port.clk, clk); connect(write_port.data, wdata); connect(write_port.mask, wmask); } #[test] fn test_memory_of_arrays() { let _n = SourceLocation::normalize_files_for_tests(); let m = check_memory_of_arrays(); dbg!(m); #[rustfmt::skip] // work around https://github.com/rust-lang/rustfmt/issues/6161 assert_export_firrtl! { m => "/test/check_memory_of_arrays.fir": r#"FIRRTL version 3.2.0 circuit check_memory_of_arrays: %[[ { "class": "firrtl.annotations.MemoryFileInlineAnnotation", "filename": "/test/check_memory_of_arrays/mem.mem", "hexOrBinary": "h", "target": "~check_memory_of_arrays|check_memory_of_arrays>mem" } ]] type Ty0 = {addr: UInt<4>, en: UInt<1>, clk: Clock, flip data: UInt<8>[2][3]} type Ty1 = {addr: UInt<4>, en: UInt<1>, clk: Clock, data: UInt<8>[2][3], mask: UInt<1>[2][3]} type Ty2 = {addr: UInt<4>, en: UInt<1>, clk: Clock, flip data: UInt<8>[6]} type Ty3 = {addr: UInt<4>, en: UInt<1>, clk: Clock, data: UInt<8>[6], mask: UInt<1>[6]} module check_memory_of_arrays: @[module-XXXXXXXXXX.rs 1:1] input raddr: UInt<4> @[module-XXXXXXXXXX.rs 2:1] output rdata: UInt<8>[2][3] @[module-XXXXXXXXXX.rs 3:1] input waddr: UInt<4> @[module-XXXXXXXXXX.rs 4:1] input wdata: UInt<8>[2][3] @[module-XXXXXXXXXX.rs 5:1] input wmask: UInt<1>[2][3] @[module-XXXXXXXXXX.rs 6:1] input clk: Clock @[module-XXXXXXXXXX.rs 7:1] mem `mem`: @[module-XXXXXXXXXX.rs 8:1] data-type => UInt<8>[6] depth => 16 read-latency => 0 write-latency => 1 read-under-write => old reader => r0 writer => w1 wire mem_r0: Ty0 @[module-XXXXXXXXXX.rs 9:1] wire mem_w1: Ty1 @[module-XXXXXXXXXX.rs 14:1] connect mem_r0.data[0][0], `mem`.r0.data[0] @[module-XXXXXXXXXX.rs 9:1] connect mem_r0.data[0][1], `mem`.r0.data[1] @[module-XXXXXXXXXX.rs 9:1] connect mem_r0.data[1][0], `mem`.r0.data[2] @[module-XXXXXXXXXX.rs 9:1] connect mem_r0.data[1][1], `mem`.r0.data[3] @[module-XXXXXXXXXX.rs 9:1] connect mem_r0.data[2][0], `mem`.r0.data[4] @[module-XXXXXXXXXX.rs 9:1] connect mem_r0.data[2][1], `mem`.r0.data[5] @[module-XXXXXXXXXX.rs 9:1] connect `mem`.w1.data[0], mem_w1.data[0][0] @[module-XXXXXXXXXX.rs 14:1] connect `mem`.w1.mask[0], mem_w1.mask[0][0] @[module-XXXXXXXXXX.rs 14:1] connect `mem`.w1.data[1], mem_w1.data[0][1] @[module-XXXXXXXXXX.rs 14:1] connect `mem`.w1.mask[1], mem_w1.mask[0][1] @[module-XXXXXXXXXX.rs 14:1] connect `mem`.w1.data[2], mem_w1.data[1][0] @[module-XXXXXXXXXX.rs 14:1] connect `mem`.w1.mask[2], mem_w1.mask[1][0] @[module-XXXXXXXXXX.rs 14:1] connect `mem`.w1.data[3], mem_w1.data[1][1] @[module-XXXXXXXXXX.rs 14:1] connect `mem`.w1.mask[3], mem_w1.mask[1][1] @[module-XXXXXXXXXX.rs 14:1] connect `mem`.w1.data[4], mem_w1.data[2][0] @[module-XXXXXXXXXX.rs 14:1] connect `mem`.w1.mask[4], mem_w1.mask[2][0] @[module-XXXXXXXXXX.rs 14:1] connect `mem`.w1.data[5], mem_w1.data[2][1] @[module-XXXXXXXXXX.rs 14:1] connect `mem`.w1.mask[5], mem_w1.mask[2][1] @[module-XXXXXXXXXX.rs 14:1] connect `mem`.r0.addr, mem_r0.addr @[module-XXXXXXXXXX.rs 9:1] connect `mem`.r0.clk, mem_r0.clk @[module-XXXXXXXXXX.rs 9:1] connect `mem`.r0.en, mem_r0.en @[module-XXXXXXXXXX.rs 9:1] connect `mem`.w1.addr, mem_w1.addr @[module-XXXXXXXXXX.rs 14:1] connect `mem`.w1.clk, mem_w1.clk @[module-XXXXXXXXXX.rs 14:1] connect `mem`.w1.en, mem_w1.en @[module-XXXXXXXXXX.rs 14:1] connect mem_r0.addr, raddr @[module-XXXXXXXXXX.rs 10:1] connect mem_r0.en, UInt<1>(0h1) @[module-XXXXXXXXXX.rs 11:1] connect mem_r0.clk, clk @[module-XXXXXXXXXX.rs 12:1] connect rdata, mem_r0.data @[module-XXXXXXXXXX.rs 13:1] connect mem_w1.addr, waddr @[module-XXXXXXXXXX.rs 15:1] connect mem_w1.en, UInt<1>(0h1) @[module-XXXXXXXXXX.rs 16:1] connect mem_w1.clk, clk @[module-XXXXXXXXXX.rs 17:1] connect mem_w1.data, wdata @[module-XXXXXXXXXX.rs 18:1] connect mem_w1.mask, wmask @[module-XXXXXXXXXX.rs 19:1] "#, "/test/check_memory_of_arrays/mem.mem": r"000000000000 020103020101 04080c080402 061b1b120903 084030201004 0a7d4b321905 0cd86c482406 0e5793623107 1000c0804008 12d9f3a25109 14e82cc8640a 16336bf2790b 18c0b020900c 1a95fb52a90d 1cb84c88c40e 1e2fa3c2e10f ", }; } #[hdl_module(outline_generated)] pub fn check_memory_of_bundle_of_arrays() { #[hdl] let raddr: UInt<4> = m.input(); #[hdl] let rdata: (Array, 2>, 3>, UInt<2>) = m.output(); #[hdl] let waddr: UInt<4> = m.input(); #[hdl] let wdata: (Array, 2>, 3>, UInt<2>) = m.input(); #[hdl] let wmask: (Array, 3>, Bool) = m.input(); #[hdl] let clk: Clock = m.input(); let mem_init = Vec::from_iter((0..0x10u8).map(|i| { ( [ [i, i * i], [(i * i).wrapping_mul(2), (i * i).wrapping_mul(3)], [(i * i).wrapping_mul(i), i * 2], ], i.cast_to_static(), ) })); #[hdl] let mut mem = memory_with_init(mem_init); let read_port = mem.new_read_port(); connect_any(read_port.addr, raddr); connect(read_port.en, true); connect(read_port.clk, clk); connect(rdata, read_port.data); let write_port = mem.new_write_port(); connect_any(write_port.addr, waddr); connect(write_port.en, true); connect(write_port.clk, clk); connect(write_port.data, wdata); connect(write_port.mask, wmask); } #[test] fn test_memory_of_bundle_of_arrays() { let _n = SourceLocation::normalize_files_for_tests(); let m = check_memory_of_bundle_of_arrays(); dbg!(m); #[rustfmt::skip] // work around https://github.com/rust-lang/rustfmt/issues/6161 assert_export_firrtl! { m => "/test/check_memory_of_bundle_of_arrays.fir": r#"FIRRTL version 3.2.0 circuit check_memory_of_bundle_of_arrays: %[[ { "class": "firrtl.annotations.MemoryFileInlineAnnotation", "filename": "/test/check_memory_of_bundle_of_arrays/mem_0.mem", "hexOrBinary": "h", "target": "~check_memory_of_bundle_of_arrays|check_memory_of_bundle_of_arrays>mem_0" }, { "class": "firrtl.annotations.MemoryFileInlineAnnotation", "filename": "/test/check_memory_of_bundle_of_arrays/mem_1.mem", "hexOrBinary": "b", "target": "~check_memory_of_bundle_of_arrays|check_memory_of_bundle_of_arrays>mem_1" } ]] type Ty0 = {`0`: UInt<8>[2][3], `1`: UInt<2>} type Ty1 = {`0`: UInt<1>[2][3], `1`: UInt<1>} type Ty2 = {addr: UInt<4>, en: UInt<1>, clk: Clock, flip data: Ty0} type Ty3 = {addr: UInt<4>, en: UInt<1>, clk: Clock, data: Ty0, mask: Ty1} type Ty4 = {addr: UInt<4>, en: UInt<1>, clk: Clock, flip data: UInt<8>[6]} type Ty5 = {addr: UInt<4>, en: UInt<1>, clk: Clock, data: UInt<8>[6], mask: UInt<1>[6]} type Ty6 = {addr: UInt<4>, en: UInt<1>, clk: Clock, flip data: UInt<2>} type Ty7 = {addr: UInt<4>, en: UInt<1>, clk: Clock, data: UInt<2>, mask: UInt<1>} module check_memory_of_bundle_of_arrays: @[module-XXXXXXXXXX.rs 1:1] input raddr: UInt<4> @[module-XXXXXXXXXX.rs 2:1] output rdata: Ty0 @[module-XXXXXXXXXX.rs 3:1] input waddr: UInt<4> @[module-XXXXXXXXXX.rs 4:1] input wdata: Ty0 @[module-XXXXXXXXXX.rs 5:1] input wmask: Ty1 @[module-XXXXXXXXXX.rs 6:1] input clk: Clock @[module-XXXXXXXXXX.rs 7:1] mem mem_0: @[module-XXXXXXXXXX.rs 8:1] data-type => UInt<8>[6] depth => 16 read-latency => 0 write-latency => 1 read-under-write => old reader => r0 writer => w1 mem mem_1: @[module-XXXXXXXXXX.rs 8:1] data-type => UInt<2> depth => 16 read-latency => 0 write-latency => 1 read-under-write => old reader => r0 writer => w1 wire mem_r0: Ty2 @[module-XXXXXXXXXX.rs 9:1] wire mem_w1: Ty3 @[module-XXXXXXXXXX.rs 14:1] connect mem_r0.data.`0`[0][0], mem_0.r0.data[0] @[module-XXXXXXXXXX.rs 9:1] connect mem_r0.data.`0`[0][1], mem_0.r0.data[1] @[module-XXXXXXXXXX.rs 9:1] connect mem_r0.data.`0`[1][0], mem_0.r0.data[2] @[module-XXXXXXXXXX.rs 9:1] connect mem_r0.data.`0`[1][1], mem_0.r0.data[3] @[module-XXXXXXXXXX.rs 9:1] connect mem_r0.data.`0`[2][0], mem_0.r0.data[4] @[module-XXXXXXXXXX.rs 9:1] connect mem_r0.data.`0`[2][1], mem_0.r0.data[5] @[module-XXXXXXXXXX.rs 9:1] connect mem_0.w1.data[0], mem_w1.data.`0`[0][0] @[module-XXXXXXXXXX.rs 14:1] connect mem_0.w1.mask[0], mem_w1.mask.`0`[0][0] @[module-XXXXXXXXXX.rs 14:1] connect mem_0.w1.data[1], mem_w1.data.`0`[0][1] @[module-XXXXXXXXXX.rs 14:1] connect mem_0.w1.mask[1], mem_w1.mask.`0`[0][1] @[module-XXXXXXXXXX.rs 14:1] connect mem_0.w1.data[2], mem_w1.data.`0`[1][0] @[module-XXXXXXXXXX.rs 14:1] connect mem_0.w1.mask[2], mem_w1.mask.`0`[1][0] @[module-XXXXXXXXXX.rs 14:1] connect mem_0.w1.data[3], mem_w1.data.`0`[1][1] @[module-XXXXXXXXXX.rs 14:1] connect mem_0.w1.mask[3], mem_w1.mask.`0`[1][1] @[module-XXXXXXXXXX.rs 14:1] connect mem_0.w1.data[4], mem_w1.data.`0`[2][0] @[module-XXXXXXXXXX.rs 14:1] connect mem_0.w1.mask[4], mem_w1.mask.`0`[2][0] @[module-XXXXXXXXXX.rs 14:1] connect mem_0.w1.data[5], mem_w1.data.`0`[2][1] @[module-XXXXXXXXXX.rs 14:1] connect mem_0.w1.mask[5], mem_w1.mask.`0`[2][1] @[module-XXXXXXXXXX.rs 14:1] connect mem_0.r0.addr, mem_r0.addr @[module-XXXXXXXXXX.rs 9:1] connect mem_0.r0.clk, mem_r0.clk @[module-XXXXXXXXXX.rs 9:1] connect mem_0.r0.en, mem_r0.en @[module-XXXXXXXXXX.rs 9:1] connect mem_0.w1.addr, mem_w1.addr @[module-XXXXXXXXXX.rs 14:1] connect mem_0.w1.clk, mem_w1.clk @[module-XXXXXXXXXX.rs 14:1] connect mem_0.w1.en, mem_w1.en @[module-XXXXXXXXXX.rs 14:1] connect mem_r0.data.`1`, mem_1.r0.data @[module-XXXXXXXXXX.rs 9:1] connect mem_1.w1.data, mem_w1.data.`1` @[module-XXXXXXXXXX.rs 14:1] connect mem_1.w1.mask, mem_w1.mask.`1` @[module-XXXXXXXXXX.rs 14:1] connect mem_1.r0.addr, mem_r0.addr @[module-XXXXXXXXXX.rs 9:1] connect mem_1.r0.clk, mem_r0.clk @[module-XXXXXXXXXX.rs 9:1] connect mem_1.r0.en, mem_r0.en @[module-XXXXXXXXXX.rs 9:1] connect mem_1.w1.addr, mem_w1.addr @[module-XXXXXXXXXX.rs 14:1] connect mem_1.w1.clk, mem_w1.clk @[module-XXXXXXXXXX.rs 14:1] connect mem_1.w1.en, mem_w1.en @[module-XXXXXXXXXX.rs 14:1] connect mem_r0.addr, raddr @[module-XXXXXXXXXX.rs 10:1] connect mem_r0.en, UInt<1>(0h1) @[module-XXXXXXXXXX.rs 11:1] connect mem_r0.clk, clk @[module-XXXXXXXXXX.rs 12:1] connect rdata, mem_r0.data @[module-XXXXXXXXXX.rs 13:1] connect mem_w1.addr, waddr @[module-XXXXXXXXXX.rs 15:1] connect mem_w1.en, UInt<1>(0h1) @[module-XXXXXXXXXX.rs 16:1] connect mem_w1.clk, clk @[module-XXXXXXXXXX.rs 17:1] connect mem_w1.data, wdata @[module-XXXXXXXXXX.rs 18:1] connect mem_w1.mask, wmask @[module-XXXXXXXXXX.rs 19:1] "#, "/test/check_memory_of_bundle_of_arrays/mem_0.mem": r"000000000000 020103020101 04080c080402 061b1b120903 084030201004 0a7d4b321905 0cd86c482406 0e5793623107 1000c0804008 12d9f3a25109 14e82cc8640a 16336bf2790b 18c0b020900c 1a95fb52a90d 1cb84c88c40e 1e2fa3c2e10f ", "/test/check_memory_of_bundle_of_arrays/mem_1.mem": r"00 01 10 11 00 01 10 11 00 01 10 11 00 01 10 11 ", }; } #[hdl_module(outline_generated)] pub fn check_memory_of_array_of_bundle() { #[hdl] let raddr: UInt<4> = m.input(); #[hdl] let rdata: Array<(UInt<8>, SInt<1>), 3> = m.output(); #[hdl] let waddr: UInt<4> = m.input(); #[hdl] let wdata: Array<(UInt<8>, SInt<1>), 3> = m.input(); #[hdl] let wmask: Array<(Bool, Bool), 3> = m.input(); #[hdl] let clk: Clock = m.input(); let mem_init = Vec::from_iter((0..0x10u8).map(|i| { [ (i, i.cast_to_static()), ((i * i), (i / 2).cast_to_static()), ((i * i).wrapping_mul(i), (i / 4).cast_to_static()), ] })); #[hdl] let mut mem = memory_with_init(mem_init); let read_port = mem.new_read_port(); connect_any(read_port.addr, raddr); connect(read_port.en, true); connect(read_port.clk, clk); connect(rdata, read_port.data); let write_port = mem.new_write_port(); connect_any(write_port.addr, waddr); connect(write_port.en, true); connect(write_port.clk, clk); connect(write_port.data, wdata); connect(write_port.mask, wmask); } #[test] fn test_memory_of_array_of_bundle() { let _n = SourceLocation::normalize_files_for_tests(); let m = check_memory_of_array_of_bundle(); dbg!(m); #[rustfmt::skip] // work around https://github.com/rust-lang/rustfmt/issues/6161 assert_export_firrtl! { m => "/test/check_memory_of_array_of_bundle.fir": r#"FIRRTL version 3.2.0 circuit check_memory_of_array_of_bundle: %[[ { "class": "firrtl.annotations.MemoryFileInlineAnnotation", "filename": "/test/check_memory_of_array_of_bundle/mem_0_0.mem", "hexOrBinary": "h", "target": "~check_memory_of_array_of_bundle|check_memory_of_array_of_bundle>mem_0_0" }, { "class": "firrtl.annotations.MemoryFileInlineAnnotation", "filename": "/test/check_memory_of_array_of_bundle/mem_0_1.mem", "hexOrBinary": "b", "target": "~check_memory_of_array_of_bundle|check_memory_of_array_of_bundle>mem_0_1" }, { "class": "firrtl.annotations.MemoryFileInlineAnnotation", "filename": "/test/check_memory_of_array_of_bundle/mem_1_0.mem", "hexOrBinary": "h", "target": "~check_memory_of_array_of_bundle|check_memory_of_array_of_bundle>mem_1_0" }, { "class": "firrtl.annotations.MemoryFileInlineAnnotation", "filename": "/test/check_memory_of_array_of_bundle/mem_1_1.mem", "hexOrBinary": "b", "target": "~check_memory_of_array_of_bundle|check_memory_of_array_of_bundle>mem_1_1" }, { "class": "firrtl.annotations.MemoryFileInlineAnnotation", "filename": "/test/check_memory_of_array_of_bundle/mem_2_0.mem", "hexOrBinary": "h", "target": "~check_memory_of_array_of_bundle|check_memory_of_array_of_bundle>mem_2_0" }, { "class": "firrtl.annotations.MemoryFileInlineAnnotation", "filename": "/test/check_memory_of_array_of_bundle/mem_2_1.mem", "hexOrBinary": "b", "target": "~check_memory_of_array_of_bundle|check_memory_of_array_of_bundle>mem_2_1" } ]] type Ty0 = {`0`: UInt<8>, `1`: SInt<1>} type Ty1 = {`0`: UInt<1>, `1`: UInt<1>} type Ty2 = {addr: UInt<4>, en: UInt<1>, clk: Clock, flip data: Ty0[3]} type Ty3 = {addr: UInt<4>, en: UInt<1>, clk: Clock, data: Ty0[3], mask: Ty1[3]} type Ty4 = {addr: UInt<4>, en: UInt<1>, clk: Clock, flip data: UInt<8>} type Ty5 = {addr: UInt<4>, en: UInt<1>, clk: Clock, data: UInt<8>, mask: UInt<1>} type Ty6 = {addr: UInt<4>, en: UInt<1>, clk: Clock, flip data: SInt<1>} type Ty7 = {addr: UInt<4>, en: UInt<1>, clk: Clock, data: SInt<1>, mask: UInt<1>} module check_memory_of_array_of_bundle: @[module-XXXXXXXXXX.rs 1:1] input raddr: UInt<4> @[module-XXXXXXXXXX.rs 2:1] output rdata: Ty0[3] @[module-XXXXXXXXXX.rs 3:1] input waddr: UInt<4> @[module-XXXXXXXXXX.rs 4:1] input wdata: Ty0[3] @[module-XXXXXXXXXX.rs 5:1] input wmask: Ty1[3] @[module-XXXXXXXXXX.rs 6:1] input clk: Clock @[module-XXXXXXXXXX.rs 7:1] mem mem_0_0: @[module-XXXXXXXXXX.rs 8:1] data-type => UInt<8> depth => 16 read-latency => 0 write-latency => 1 read-under-write => old reader => r0 writer => w1 mem mem_0_1: @[module-XXXXXXXXXX.rs 8:1] data-type => SInt<1> depth => 16 read-latency => 0 write-latency => 1 read-under-write => old reader => r0 writer => w1 mem mem_1_0: @[module-XXXXXXXXXX.rs 8:1] data-type => UInt<8> depth => 16 read-latency => 0 write-latency => 1 read-under-write => old reader => r0 writer => w1 mem mem_1_1: @[module-XXXXXXXXXX.rs 8:1] data-type => SInt<1> depth => 16 read-latency => 0 write-latency => 1 read-under-write => old reader => r0 writer => w1 mem mem_2_0: @[module-XXXXXXXXXX.rs 8:1] data-type => UInt<8> depth => 16 read-latency => 0 write-latency => 1 read-under-write => old reader => r0 writer => w1 mem mem_2_1: @[module-XXXXXXXXXX.rs 8:1] data-type => SInt<1> depth => 16 read-latency => 0 write-latency => 1 read-under-write => old reader => r0 writer => w1 wire mem_r0: Ty2 @[module-XXXXXXXXXX.rs 9:1] wire mem_w1: Ty3 @[module-XXXXXXXXXX.rs 14:1] connect mem_r0.data[0].`0`, mem_0_0.r0.data @[module-XXXXXXXXXX.rs 9:1] connect mem_0_0.w1.data, mem_w1.data[0].`0` @[module-XXXXXXXXXX.rs 14:1] connect mem_0_0.w1.mask, mem_w1.mask[0].`0` @[module-XXXXXXXXXX.rs 14:1] connect mem_0_0.r0.addr, mem_r0.addr @[module-XXXXXXXXXX.rs 9:1] connect mem_0_0.r0.clk, mem_r0.clk @[module-XXXXXXXXXX.rs 9:1] connect mem_0_0.r0.en, mem_r0.en @[module-XXXXXXXXXX.rs 9:1] connect mem_0_0.w1.addr, mem_w1.addr @[module-XXXXXXXXXX.rs 14:1] connect mem_0_0.w1.clk, mem_w1.clk @[module-XXXXXXXXXX.rs 14:1] connect mem_0_0.w1.en, mem_w1.en @[module-XXXXXXXXXX.rs 14:1] connect mem_r0.data[0].`1`, mem_0_1.r0.data @[module-XXXXXXXXXX.rs 9:1] connect mem_0_1.w1.data, mem_w1.data[0].`1` @[module-XXXXXXXXXX.rs 14:1] connect mem_0_1.w1.mask, mem_w1.mask[0].`1` @[module-XXXXXXXXXX.rs 14:1] connect mem_0_1.r0.addr, mem_r0.addr @[module-XXXXXXXXXX.rs 9:1] connect mem_0_1.r0.clk, mem_r0.clk @[module-XXXXXXXXXX.rs 9:1] connect mem_0_1.r0.en, mem_r0.en @[module-XXXXXXXXXX.rs 9:1] connect mem_0_1.w1.addr, mem_w1.addr @[module-XXXXXXXXXX.rs 14:1] connect mem_0_1.w1.clk, mem_w1.clk @[module-XXXXXXXXXX.rs 14:1] connect mem_0_1.w1.en, mem_w1.en @[module-XXXXXXXXXX.rs 14:1] connect mem_r0.data[1].`0`, mem_1_0.r0.data @[module-XXXXXXXXXX.rs 9:1] connect mem_1_0.w1.data, mem_w1.data[1].`0` @[module-XXXXXXXXXX.rs 14:1] connect mem_1_0.w1.mask, mem_w1.mask[1].`0` @[module-XXXXXXXXXX.rs 14:1] connect mem_1_0.r0.addr, mem_r0.addr @[module-XXXXXXXXXX.rs 9:1] connect mem_1_0.r0.clk, mem_r0.clk @[module-XXXXXXXXXX.rs 9:1] connect mem_1_0.r0.en, mem_r0.en @[module-XXXXXXXXXX.rs 9:1] connect mem_1_0.w1.addr, mem_w1.addr @[module-XXXXXXXXXX.rs 14:1] connect mem_1_0.w1.clk, mem_w1.clk @[module-XXXXXXXXXX.rs 14:1] connect mem_1_0.w1.en, mem_w1.en @[module-XXXXXXXXXX.rs 14:1] connect mem_r0.data[1].`1`, mem_1_1.r0.data @[module-XXXXXXXXXX.rs 9:1] connect mem_1_1.w1.data, mem_w1.data[1].`1` @[module-XXXXXXXXXX.rs 14:1] connect mem_1_1.w1.mask, mem_w1.mask[1].`1` @[module-XXXXXXXXXX.rs 14:1] connect mem_1_1.r0.addr, mem_r0.addr @[module-XXXXXXXXXX.rs 9:1] connect mem_1_1.r0.clk, mem_r0.clk @[module-XXXXXXXXXX.rs 9:1] connect mem_1_1.r0.en, mem_r0.en @[module-XXXXXXXXXX.rs 9:1] connect mem_1_1.w1.addr, mem_w1.addr @[module-XXXXXXXXXX.rs 14:1] connect mem_1_1.w1.clk, mem_w1.clk @[module-XXXXXXXXXX.rs 14:1] connect mem_1_1.w1.en, mem_w1.en @[module-XXXXXXXXXX.rs 14:1] connect mem_r0.data[2].`0`, mem_2_0.r0.data @[module-XXXXXXXXXX.rs 9:1] connect mem_2_0.w1.data, mem_w1.data[2].`0` @[module-XXXXXXXXXX.rs 14:1] connect mem_2_0.w1.mask, mem_w1.mask[2].`0` @[module-XXXXXXXXXX.rs 14:1] connect mem_2_0.r0.addr, mem_r0.addr @[module-XXXXXXXXXX.rs 9:1] connect mem_2_0.r0.clk, mem_r0.clk @[module-XXXXXXXXXX.rs 9:1] connect mem_2_0.r0.en, mem_r0.en @[module-XXXXXXXXXX.rs 9:1] connect mem_2_0.w1.addr, mem_w1.addr @[module-XXXXXXXXXX.rs 14:1] connect mem_2_0.w1.clk, mem_w1.clk @[module-XXXXXXXXXX.rs 14:1] connect mem_2_0.w1.en, mem_w1.en @[module-XXXXXXXXXX.rs 14:1] connect mem_r0.data[2].`1`, mem_2_1.r0.data @[module-XXXXXXXXXX.rs 9:1] connect mem_2_1.w1.data, mem_w1.data[2].`1` @[module-XXXXXXXXXX.rs 14:1] connect mem_2_1.w1.mask, mem_w1.mask[2].`1` @[module-XXXXXXXXXX.rs 14:1] connect mem_2_1.r0.addr, mem_r0.addr @[module-XXXXXXXXXX.rs 9:1] connect mem_2_1.r0.clk, mem_r0.clk @[module-XXXXXXXXXX.rs 9:1] connect mem_2_1.r0.en, mem_r0.en @[module-XXXXXXXXXX.rs 9:1] connect mem_2_1.w1.addr, mem_w1.addr @[module-XXXXXXXXXX.rs 14:1] connect mem_2_1.w1.clk, mem_w1.clk @[module-XXXXXXXXXX.rs 14:1] connect mem_2_1.w1.en, mem_w1.en @[module-XXXXXXXXXX.rs 14:1] connect mem_r0.addr, raddr @[module-XXXXXXXXXX.rs 10:1] connect mem_r0.en, UInt<1>(0h1) @[module-XXXXXXXXXX.rs 11:1] connect mem_r0.clk, clk @[module-XXXXXXXXXX.rs 12:1] connect rdata, mem_r0.data @[module-XXXXXXXXXX.rs 13:1] connect mem_w1.addr, waddr @[module-XXXXXXXXXX.rs 15:1] connect mem_w1.en, UInt<1>(0h1) @[module-XXXXXXXXXX.rs 16:1] connect mem_w1.clk, clk @[module-XXXXXXXXXX.rs 17:1] connect mem_w1.data, wdata @[module-XXXXXXXXXX.rs 18:1] connect mem_w1.mask, wmask @[module-XXXXXXXXXX.rs 19:1] "#, "/test/check_memory_of_array_of_bundle/mem_0_0.mem": r"00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f ", "/test/check_memory_of_array_of_bundle/mem_0_1.mem": r"0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 ", "/test/check_memory_of_array_of_bundle/mem_1_0.mem": r"00 01 04 09 10 19 24 31 40 51 64 79 90 a9 c4 e1 ", "/test/check_memory_of_array_of_bundle/mem_1_1.mem": r"0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 ", "/test/check_memory_of_array_of_bundle/mem_2_0.mem": r"00 01 08 1b 40 7d d8 57 00 d9 e8 33 c0 95 b8 2f ", "/test/check_memory_of_array_of_bundle/mem_2_1.mem": r"0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1 ", }; } #[hdl_module(outline_generated)] pub fn check_memory_of_bundle() { #[hdl] let raddr: UInt<4> = m.input(); #[hdl] let rdata: (UInt<8>, SInt<1>) = m.output(); #[hdl] let waddr: UInt<4> = m.input(); #[hdl] let wdata: (UInt<8>, SInt<1>) = m.input(); #[hdl] let wmask: (Bool, Bool) = m.input(); #[hdl] let clk: Clock = m.input(); let mem_init = Vec::from_iter((0..0x10u8).map(|i| (i ^ 3, (i ^ (i / 2)).cast_to_static()))); #[hdl] let mut mem = memory_with_init(mem_init); let read_port = mem.new_read_port(); connect_any(read_port.addr, raddr); connect(read_port.en, true); connect(read_port.clk, clk); connect(rdata, read_port.data); let write_port = mem.new_write_port(); connect_any(write_port.addr, waddr); connect(write_port.en, true); connect(write_port.clk, clk); connect(write_port.data, wdata); connect(write_port.mask, wmask); } #[test] fn test_memory_of_bundle() { let _n = SourceLocation::normalize_files_for_tests(); let m = check_memory_of_bundle(); dbg!(m); #[rustfmt::skip] // work around https://github.com/rust-lang/rustfmt/issues/6161 assert_export_firrtl! { m => "/test/check_memory_of_bundle.fir": r#"FIRRTL version 3.2.0 circuit check_memory_of_bundle: %[[ { "class": "firrtl.annotations.MemoryFileInlineAnnotation", "filename": "/test/check_memory_of_bundle/mem_0.mem", "hexOrBinary": "h", "target": "~check_memory_of_bundle|check_memory_of_bundle>mem_0" }, { "class": "firrtl.annotations.MemoryFileInlineAnnotation", "filename": "/test/check_memory_of_bundle/mem_1.mem", "hexOrBinary": "b", "target": "~check_memory_of_bundle|check_memory_of_bundle>mem_1" } ]] type Ty0 = {`0`: UInt<8>, `1`: SInt<1>} type Ty1 = {`0`: UInt<1>, `1`: UInt<1>} type Ty2 = {addr: UInt<4>, en: UInt<1>, clk: Clock, flip data: Ty0} type Ty3 = {addr: UInt<4>, en: UInt<1>, clk: Clock, data: Ty0, mask: Ty1} type Ty4 = {addr: UInt<4>, en: UInt<1>, clk: Clock, flip data: UInt<8>} type Ty5 = {addr: UInt<4>, en: UInt<1>, clk: Clock, data: UInt<8>, mask: UInt<1>} type Ty6 = {addr: UInt<4>, en: UInt<1>, clk: Clock, flip data: SInt<1>} type Ty7 = {addr: UInt<4>, en: UInt<1>, clk: Clock, data: SInt<1>, mask: UInt<1>} module check_memory_of_bundle: @[module-XXXXXXXXXX.rs 1:1] input raddr: UInt<4> @[module-XXXXXXXXXX.rs 2:1] output rdata: Ty0 @[module-XXXXXXXXXX.rs 3:1] input waddr: UInt<4> @[module-XXXXXXXXXX.rs 4:1] input wdata: Ty0 @[module-XXXXXXXXXX.rs 5:1] input wmask: Ty1 @[module-XXXXXXXXXX.rs 6:1] input clk: Clock @[module-XXXXXXXXXX.rs 7:1] mem mem_0: @[module-XXXXXXXXXX.rs 8:1] data-type => UInt<8> depth => 16 read-latency => 0 write-latency => 1 read-under-write => old reader => r0 writer => w1 mem mem_1: @[module-XXXXXXXXXX.rs 8:1] data-type => SInt<1> depth => 16 read-latency => 0 write-latency => 1 read-under-write => old reader => r0 writer => w1 wire mem_r0: Ty2 @[module-XXXXXXXXXX.rs 9:1] wire mem_w1: Ty3 @[module-XXXXXXXXXX.rs 14:1] connect mem_r0.data.`0`, mem_0.r0.data @[module-XXXXXXXXXX.rs 9:1] connect mem_0.w1.data, mem_w1.data.`0` @[module-XXXXXXXXXX.rs 14:1] connect mem_0.w1.mask, mem_w1.mask.`0` @[module-XXXXXXXXXX.rs 14:1] connect mem_0.r0.addr, mem_r0.addr @[module-XXXXXXXXXX.rs 9:1] connect mem_0.r0.clk, mem_r0.clk @[module-XXXXXXXXXX.rs 9:1] connect mem_0.r0.en, mem_r0.en @[module-XXXXXXXXXX.rs 9:1] connect mem_0.w1.addr, mem_w1.addr @[module-XXXXXXXXXX.rs 14:1] connect mem_0.w1.clk, mem_w1.clk @[module-XXXXXXXXXX.rs 14:1] connect mem_0.w1.en, mem_w1.en @[module-XXXXXXXXXX.rs 14:1] connect mem_r0.data.`1`, mem_1.r0.data @[module-XXXXXXXXXX.rs 9:1] connect mem_1.w1.data, mem_w1.data.`1` @[module-XXXXXXXXXX.rs 14:1] connect mem_1.w1.mask, mem_w1.mask.`1` @[module-XXXXXXXXXX.rs 14:1] connect mem_1.r0.addr, mem_r0.addr @[module-XXXXXXXXXX.rs 9:1] connect mem_1.r0.clk, mem_r0.clk @[module-XXXXXXXXXX.rs 9:1] connect mem_1.r0.en, mem_r0.en @[module-XXXXXXXXXX.rs 9:1] connect mem_1.w1.addr, mem_w1.addr @[module-XXXXXXXXXX.rs 14:1] connect mem_1.w1.clk, mem_w1.clk @[module-XXXXXXXXXX.rs 14:1] connect mem_1.w1.en, mem_w1.en @[module-XXXXXXXXXX.rs 14:1] connect mem_r0.addr, raddr @[module-XXXXXXXXXX.rs 10:1] connect mem_r0.en, UInt<1>(0h1) @[module-XXXXXXXXXX.rs 11:1] connect mem_r0.clk, clk @[module-XXXXXXXXXX.rs 12:1] connect rdata, mem_r0.data @[module-XXXXXXXXXX.rs 13:1] connect mem_w1.addr, waddr @[module-XXXXXXXXXX.rs 15:1] connect mem_w1.en, UInt<1>(0h1) @[module-XXXXXXXXXX.rs 16:1] connect mem_w1.clk, clk @[module-XXXXXXXXXX.rs 17:1] connect mem_w1.data, wdata @[module-XXXXXXXXXX.rs 18:1] connect mem_w1.mask, wmask @[module-XXXXXXXXXX.rs 19:1] "#, "/test/check_memory_of_bundle/mem_0.mem": r"03 02 01 00 07 06 05 04 0b 0a 09 08 0f 0e 0d 0c ", "/test/check_memory_of_bundle/mem_1.mem": r"0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 ", }; } #[hdl_module(outline_generated)] pub fn check_memory_of_enum() { #[hdl] let raddr: UInt<8> = m.input(); #[hdl] let rdata: TestEnum = m.output(); #[hdl] let waddr: UInt<8> = m.input(); #[hdl] let wdata: TestEnum = m.input(); #[hdl] let wmask: Bool = m.input(); #[hdl] let clk: Clock = m.input(); let mem_init = Vec::from_iter((0..0x10u8).map(|i| match i { 0 => TestEnum.A(), 1..=3 => TestEnum.C([i == 1, i == 2, i == 3]), _ => TestEnum.B(i), })); #[hdl] let mut mem = memory_with_init(mem_init); let read_port = mem.new_read_port(); connect_any(read_port.addr, raddr); connect(read_port.en, true); connect(read_port.clk, clk); connect(rdata, read_port.data); let write_port = mem.new_write_port(); connect_any(write_port.addr, waddr); connect(write_port.en, true); connect(write_port.clk, clk); connect(write_port.data, wdata); connect(write_port.mask, wmask); } #[test] fn test_memory_of_enum() { let _n = SourceLocation::normalize_files_for_tests(); let m = check_memory_of_enum(); dbg!(m); #[rustfmt::skip] // work around https://github.com/rust-lang/rustfmt/issues/6161 assert_export_firrtl! { m => options: ExportOptions { simplify_enums: None, ..ExportOptions::default() }, "/test/check_memory_of_enum.fir": r#"FIRRTL version 3.2.0 circuit check_memory_of_enum: %[[ { "class": "firrtl.annotations.MemoryFileInlineAnnotation", "filename": "/test/check_memory_of_enum/mem.mem", "hexOrBinary": "b", "target": "~check_memory_of_enum|check_memory_of_enum>mem" } ]] type Ty0 = {|A, B: UInt<8>, C: UInt<1>[3]|} type Ty1 = {addr: UInt<4>, en: UInt<1>, clk: Clock, flip data: Ty0} type Ty2 = {addr: UInt<4>, en: UInt<1>, clk: Clock, data: Ty0, mask: UInt<1>} type Ty3 = {addr: UInt<4>, en: UInt<1>, clk: Clock, flip data: UInt<10>} type Ty4 = {addr: UInt<4>, en: UInt<1>, clk: Clock, data: UInt<10>, mask: UInt<1>} module check_memory_of_enum: @[module-XXXXXXXXXX.rs 1:1] input raddr: UInt<8> @[module-XXXXXXXXXX.rs 2:1] output rdata: Ty0 @[module-XXXXXXXXXX.rs 3:1] input waddr: UInt<8> @[module-XXXXXXXXXX.rs 4:1] input wdata: Ty0 @[module-XXXXXXXXXX.rs 5:1] input wmask: UInt<1> @[module-XXXXXXXXXX.rs 6:1] input clk: Clock @[module-XXXXXXXXXX.rs 7:1] mem `mem`: @[module-XXXXXXXXXX.rs 8:1] data-type => UInt<10> depth => 16 read-latency => 0 write-latency => 1 read-under-write => old reader => r0 writer => w1 wire mem_r0: Ty1 @[module-XXXXXXXXXX.rs 9:1] wire mem_w1: Ty2 @[module-XXXXXXXXXX.rs 14:1] wire _cast_bits_to_enum_expr: Ty0 wire _cast_bits_to_enum_expr_body: UInt<8> connect _cast_bits_to_enum_expr_body, head(`mem`.r0.data, 8) when eq(UInt<2>(0), tail(`mem`.r0.data, 8)): connect _cast_bits_to_enum_expr, {|A, B: UInt<8>, C: UInt<1>[3]|}(A) else when eq(UInt<2>(1), tail(`mem`.r0.data, 8)): connect _cast_bits_to_enum_expr, {|A, B: UInt<8>, C: UInt<1>[3]|}(B, _cast_bits_to_enum_expr_body) else: wire _cast_bits_to_array_expr: UInt<1>[3] wire _cast_bits_to_array_expr_flattened: UInt<1>[3] connect _cast_bits_to_array_expr_flattened[0], bits(_cast_bits_to_enum_expr_body, 0, 0) connect _cast_bits_to_array_expr[0], _cast_bits_to_array_expr_flattened[0] connect _cast_bits_to_array_expr_flattened[1], bits(_cast_bits_to_enum_expr_body, 1, 1) connect _cast_bits_to_array_expr[1], _cast_bits_to_array_expr_flattened[1] connect _cast_bits_to_array_expr_flattened[2], bits(_cast_bits_to_enum_expr_body, 2, 2) connect _cast_bits_to_array_expr[2], _cast_bits_to_array_expr_flattened[2] connect _cast_bits_to_enum_expr, {|A, B: UInt<8>, C: UInt<1>[3]|}(C, _cast_bits_to_array_expr) connect mem_r0.data, _cast_bits_to_enum_expr @[module-XXXXXXXXXX.rs 9:1] wire _cast_enum_to_bits_expr: UInt<10> match mem_w1.data: A: connect _cast_enum_to_bits_expr, UInt<10>(0) B(_cast_enum_to_bits_expr_B): connect _cast_enum_to_bits_expr, pad(cat(_cast_enum_to_bits_expr_B, UInt<2>(1)), 10) C(_cast_enum_to_bits_expr_C): wire _cast_array_to_bits_expr: UInt<1>[3] connect _cast_array_to_bits_expr[0], _cast_enum_to_bits_expr_C[0] connect _cast_array_to_bits_expr[1], _cast_enum_to_bits_expr_C[1] connect _cast_array_to_bits_expr[2], _cast_enum_to_bits_expr_C[2] wire _cast_to_bits_expr: UInt<3> connect _cast_to_bits_expr, cat(_cast_array_to_bits_expr[2], cat(_cast_array_to_bits_expr[1], _cast_array_to_bits_expr[0])) connect _cast_enum_to_bits_expr, pad(cat(_cast_to_bits_expr, UInt<2>(2)), 10) connect `mem`.w1.data, _cast_enum_to_bits_expr @[module-XXXXXXXXXX.rs 14:1] connect `mem`.w1.mask, mem_w1.mask @[module-XXXXXXXXXX.rs 14:1] connect `mem`.r0.addr, mem_r0.addr @[module-XXXXXXXXXX.rs 9:1] connect `mem`.r0.clk, mem_r0.clk @[module-XXXXXXXXXX.rs 9:1] connect `mem`.r0.en, mem_r0.en @[module-XXXXXXXXXX.rs 9:1] connect `mem`.w1.addr, mem_w1.addr @[module-XXXXXXXXXX.rs 14:1] connect `mem`.w1.clk, mem_w1.clk @[module-XXXXXXXXXX.rs 14:1] connect `mem`.w1.en, mem_w1.en @[module-XXXXXXXXXX.rs 14:1] ; connect different types: ; lhs: UInt<4> ; rhs: UInt<8> connect mem_r0.addr, raddr @[module-XXXXXXXXXX.rs 10:1] connect mem_r0.en, UInt<1>(0h1) @[module-XXXXXXXXXX.rs 11:1] connect mem_r0.clk, clk @[module-XXXXXXXXXX.rs 12:1] connect rdata, mem_r0.data @[module-XXXXXXXXXX.rs 13:1] ; connect different types: ; lhs: UInt<4> ; rhs: UInt<8> connect mem_w1.addr, waddr @[module-XXXXXXXXXX.rs 15:1] connect mem_w1.en, UInt<1>(0h1) @[module-XXXXXXXXXX.rs 16:1] connect mem_w1.clk, clk @[module-XXXXXXXXXX.rs 17:1] connect mem_w1.data, wdata @[module-XXXXXXXXXX.rs 18:1] connect mem_w1.mask, wmask @[module-XXXXXXXXXX.rs 19:1] "#, "/test/check_memory_of_enum/mem.mem": r"0000000000 0000000110 0000001010 0000010010 0000010001 0000010101 0000011001 0000011101 0000100001 0000100101 0000101001 0000101101 0000110001 0000110101 0000111001 0000111101 ", }; #[rustfmt::skip] // work around https://github.com/rust-lang/rustfmt/issues/6161 assert_export_firrtl! { m => options: ExportOptions { simplify_enums: Some(SimplifyEnumsKind::SimplifyToEnumsWithNoBody), ..ExportOptions::default() }, "/test/check_memory_of_enum.fir": r#"FIRRTL version 3.2.0 circuit check_memory_of_enum: %[[ { "class": "firrtl.annotations.MemoryFileInlineAnnotation", "filename": "/test/check_memory_of_enum/mem_tag.mem", "hexOrBinary": "b", "target": "~check_memory_of_enum|check_memory_of_enum>mem_tag" }, { "class": "firrtl.annotations.MemoryFileInlineAnnotation", "filename": "/test/check_memory_of_enum/mem_body.mem", "hexOrBinary": "h", "target": "~check_memory_of_enum|check_memory_of_enum>mem_body" } ]] type Ty0 = {|A, B, C|} type Ty1 = {tag: Ty0, body: UInt<8>} type Ty2 = {addr: UInt<4>, en: UInt<1>, clk: Clock, flip data: Ty1} type Ty3 = {tag: UInt<1>, body: UInt<1>} type Ty4 = {addr: UInt<4>, en: UInt<1>, clk: Clock, data: Ty1, mask: Ty3} type Ty5 = {addr: UInt<4>, en: UInt<1>, clk: Clock, flip data: UInt<2>} type Ty6 = {addr: UInt<4>, en: UInt<1>, clk: Clock, data: UInt<2>, mask: UInt<1>} type Ty7 = {addr: UInt<4>, en: UInt<1>, clk: Clock, flip data: UInt<8>} type Ty8 = {addr: UInt<4>, en: UInt<1>, clk: Clock, data: UInt<8>, mask: UInt<1>} type Ty9 = {addr: UInt<4>, en: UInt<1>, clk: Clock, data: Ty1, mask: UInt<1>} module check_memory_of_enum: @[module-XXXXXXXXXX.rs 1:1] input raddr: UInt<8> @[module-XXXXXXXXXX.rs 2:1] output rdata: Ty1 @[module-XXXXXXXXXX.rs 3:1] input waddr: UInt<8> @[module-XXXXXXXXXX.rs 4:1] input wdata: Ty1 @[module-XXXXXXXXXX.rs 5:1] input wmask: UInt<1> @[module-XXXXXXXXXX.rs 6:1] input clk: Clock @[module-XXXXXXXXXX.rs 7:1] mem mem_tag: @[module-XXXXXXXXXX.rs 8:1] data-type => UInt<2> depth => 16 read-latency => 0 write-latency => 1 read-under-write => old reader => r0 writer => w1 mem mem_body: @[module-XXXXXXXXXX.rs 8:1] data-type => UInt<8> depth => 16 read-latency => 0 write-latency => 1 read-under-write => old reader => r0 writer => w1 wire mem_r0: Ty2 @[module-XXXXXXXXXX.rs 9:1] wire mem_w1: Ty4 @[module-XXXXXXXXXX.rs 14:1] wire _cast_bits_to_enum_expr: Ty0 when eq(UInt<2>(0), tail(mem_tag.r0.data, 0)): connect _cast_bits_to_enum_expr, {|A, B, C|}(A) else when eq(UInt<2>(1), tail(mem_tag.r0.data, 0)): connect _cast_bits_to_enum_expr, {|A, B, C|}(B) else: connect _cast_bits_to_enum_expr, {|A, B, C|}(C) connect mem_r0.data.tag, _cast_bits_to_enum_expr @[module-XXXXXXXXXX.rs 9:1] wire _cast_enum_to_bits_expr: UInt<2> match mem_w1.data.tag: A: connect _cast_enum_to_bits_expr, UInt<2>(0) B: connect _cast_enum_to_bits_expr, UInt<2>(1) C: connect _cast_enum_to_bits_expr, UInt<2>(2) connect mem_tag.w1.data, _cast_enum_to_bits_expr @[module-XXXXXXXXXX.rs 14:1] connect mem_tag.w1.mask, mem_w1.mask.tag @[module-XXXXXXXXXX.rs 14:1] connect mem_tag.r0.addr, mem_r0.addr @[module-XXXXXXXXXX.rs 9:1] connect mem_tag.r0.clk, mem_r0.clk @[module-XXXXXXXXXX.rs 9:1] connect mem_tag.r0.en, mem_r0.en @[module-XXXXXXXXXX.rs 9:1] connect mem_tag.w1.addr, mem_w1.addr @[module-XXXXXXXXXX.rs 14:1] connect mem_tag.w1.clk, mem_w1.clk @[module-XXXXXXXXXX.rs 14:1] connect mem_tag.w1.en, mem_w1.en @[module-XXXXXXXXXX.rs 14:1] connect mem_r0.data.body, mem_body.r0.data @[module-XXXXXXXXXX.rs 9:1] connect mem_body.w1.data, mem_w1.data.body @[module-XXXXXXXXXX.rs 14:1] connect mem_body.w1.mask, mem_w1.mask.body @[module-XXXXXXXXXX.rs 14:1] connect mem_body.r0.addr, mem_r0.addr @[module-XXXXXXXXXX.rs 9:1] connect mem_body.r0.clk, mem_r0.clk @[module-XXXXXXXXXX.rs 9:1] connect mem_body.r0.en, mem_r0.en @[module-XXXXXXXXXX.rs 9:1] connect mem_body.w1.addr, mem_w1.addr @[module-XXXXXXXXXX.rs 14:1] connect mem_body.w1.clk, mem_w1.clk @[module-XXXXXXXXXX.rs 14:1] connect mem_body.w1.en, mem_w1.en @[module-XXXXXXXXXX.rs 14:1] wire mem_w1_1: Ty9 @[module-XXXXXXXXXX.rs 14:1] connect mem_w1.addr, mem_w1_1.addr @[module-XXXXXXXXXX.rs 14:1] connect mem_w1.en, mem_w1_1.en @[module-XXXXXXXXXX.rs 14:1] connect mem_w1.clk, mem_w1_1.clk @[module-XXXXXXXXXX.rs 14:1] connect mem_w1.data, mem_w1_1.data @[module-XXXXXXXXXX.rs 14:1] connect mem_w1.mask.tag, mem_w1_1.mask @[module-XXXXXXXXXX.rs 14:1] connect mem_w1.mask.body, mem_w1_1.mask @[module-XXXXXXXXXX.rs 14:1] ; connect different types: ; lhs: UInt<4> ; rhs: UInt<8> connect mem_r0.addr, raddr @[module-XXXXXXXXXX.rs 10:1] connect mem_r0.en, UInt<1>(0h1) @[module-XXXXXXXXXX.rs 11:1] connect mem_r0.clk, clk @[module-XXXXXXXXXX.rs 12:1] connect rdata, mem_r0.data @[module-XXXXXXXXXX.rs 13:1] ; connect different types: ; lhs: UInt<4> ; rhs: UInt<8> connect mem_w1_1.addr, waddr @[module-XXXXXXXXXX.rs 15:1] connect mem_w1_1.en, UInt<1>(0h1) @[module-XXXXXXXXXX.rs 16:1] connect mem_w1_1.clk, clk @[module-XXXXXXXXXX.rs 17:1] connect mem_w1_1.data, wdata @[module-XXXXXXXXXX.rs 18:1] connect mem_w1_1.mask, wmask @[module-XXXXXXXXXX.rs 19:1] "#, "/test/check_memory_of_enum/mem_body.mem": r"00 01 02 04 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f ", "/test/check_memory_of_enum/mem_tag.mem": r"00 10 10 10 01 01 01 01 01 01 01 01 01 01 01 01 ", }; #[rustfmt::skip] // work around https://github.com/rust-lang/rustfmt/issues/6161 assert_export_firrtl! { m => options: ExportOptions { ..ExportOptions::default() }, "/test/check_memory_of_enum.fir": r#"FIRRTL version 3.2.0 circuit check_memory_of_enum: %[[ { "class": "firrtl.annotations.MemoryFileInlineAnnotation", "filename": "/test/check_memory_of_enum/mem_tag.mem", "hexOrBinary": "b", "target": "~check_memory_of_enum|check_memory_of_enum>mem_tag" }, { "class": "firrtl.annotations.MemoryFileInlineAnnotation", "filename": "/test/check_memory_of_enum/mem_body.mem", "hexOrBinary": "h", "target": "~check_memory_of_enum|check_memory_of_enum>mem_body" } ]] type Ty0 = {tag: UInt<2>, body: UInt<8>} type Ty1 = {addr: UInt<4>, en: UInt<1>, clk: Clock, flip data: Ty0} type Ty2 = {tag: UInt<1>, body: UInt<1>} type Ty3 = {addr: UInt<4>, en: UInt<1>, clk: Clock, data: Ty0, mask: Ty2} type Ty4 = {addr: UInt<4>, en: UInt<1>, clk: Clock, flip data: UInt<2>} type Ty5 = {addr: UInt<4>, en: UInt<1>, clk: Clock, data: UInt<2>, mask: UInt<1>} type Ty6 = {addr: UInt<4>, en: UInt<1>, clk: Clock, flip data: UInt<8>} type Ty7 = {addr: UInt<4>, en: UInt<1>, clk: Clock, data: UInt<8>, mask: UInt<1>} type Ty8 = {addr: UInt<4>, en: UInt<1>, clk: Clock, data: Ty0, mask: UInt<1>} module check_memory_of_enum: @[module-XXXXXXXXXX.rs 1:1] input raddr: UInt<8> @[module-XXXXXXXXXX.rs 2:1] output rdata: Ty0 @[module-XXXXXXXXXX.rs 3:1] input waddr: UInt<8> @[module-XXXXXXXXXX.rs 4:1] input wdata: Ty0 @[module-XXXXXXXXXX.rs 5:1] input wmask: UInt<1> @[module-XXXXXXXXXX.rs 6:1] input clk: Clock @[module-XXXXXXXXXX.rs 7:1] mem mem_tag: @[module-XXXXXXXXXX.rs 8:1] data-type => UInt<2> depth => 16 read-latency => 0 write-latency => 1 read-under-write => old reader => r0 writer => w1 mem mem_body: @[module-XXXXXXXXXX.rs 8:1] data-type => UInt<8> depth => 16 read-latency => 0 write-latency => 1 read-under-write => old reader => r0 writer => w1 wire mem_r0: Ty1 @[module-XXXXXXXXXX.rs 9:1] wire mem_w1: Ty3 @[module-XXXXXXXXXX.rs 14:1] connect mem_r0.data.tag, mem_tag.r0.data @[module-XXXXXXXXXX.rs 9:1] connect mem_tag.w1.data, mem_w1.data.tag @[module-XXXXXXXXXX.rs 14:1] connect mem_tag.w1.mask, mem_w1.mask.tag @[module-XXXXXXXXXX.rs 14:1] connect mem_tag.r0.addr, mem_r0.addr @[module-XXXXXXXXXX.rs 9:1] connect mem_tag.r0.clk, mem_r0.clk @[module-XXXXXXXXXX.rs 9:1] connect mem_tag.r0.en, mem_r0.en @[module-XXXXXXXXXX.rs 9:1] connect mem_tag.w1.addr, mem_w1.addr @[module-XXXXXXXXXX.rs 14:1] connect mem_tag.w1.clk, mem_w1.clk @[module-XXXXXXXXXX.rs 14:1] connect mem_tag.w1.en, mem_w1.en @[module-XXXXXXXXXX.rs 14:1] connect mem_r0.data.body, mem_body.r0.data @[module-XXXXXXXXXX.rs 9:1] connect mem_body.w1.data, mem_w1.data.body @[module-XXXXXXXXXX.rs 14:1] connect mem_body.w1.mask, mem_w1.mask.body @[module-XXXXXXXXXX.rs 14:1] connect mem_body.r0.addr, mem_r0.addr @[module-XXXXXXXXXX.rs 9:1] connect mem_body.r0.clk, mem_r0.clk @[module-XXXXXXXXXX.rs 9:1] connect mem_body.r0.en, mem_r0.en @[module-XXXXXXXXXX.rs 9:1] connect mem_body.w1.addr, mem_w1.addr @[module-XXXXXXXXXX.rs 14:1] connect mem_body.w1.clk, mem_w1.clk @[module-XXXXXXXXXX.rs 14:1] connect mem_body.w1.en, mem_w1.en @[module-XXXXXXXXXX.rs 14:1] wire mem_w1_1: Ty8 @[module-XXXXXXXXXX.rs 14:1] connect mem_w1.addr, mem_w1_1.addr @[module-XXXXXXXXXX.rs 14:1] connect mem_w1.en, mem_w1_1.en @[module-XXXXXXXXXX.rs 14:1] connect mem_w1.clk, mem_w1_1.clk @[module-XXXXXXXXXX.rs 14:1] connect mem_w1.data, mem_w1_1.data @[module-XXXXXXXXXX.rs 14:1] connect mem_w1.mask.tag, mem_w1_1.mask @[module-XXXXXXXXXX.rs 14:1] connect mem_w1.mask.body, mem_w1_1.mask @[module-XXXXXXXXXX.rs 14:1] ; connect different types: ; lhs: UInt<4> ; rhs: UInt<8> connect mem_r0.addr, raddr @[module-XXXXXXXXXX.rs 10:1] connect mem_r0.en, UInt<1>(0h1) @[module-XXXXXXXXXX.rs 11:1] connect mem_r0.clk, clk @[module-XXXXXXXXXX.rs 12:1] connect rdata, mem_r0.data @[module-XXXXXXXXXX.rs 13:1] ; connect different types: ; lhs: UInt<4> ; rhs: UInt<8> connect mem_w1_1.addr, waddr @[module-XXXXXXXXXX.rs 15:1] connect mem_w1_1.en, UInt<1>(0h1) @[module-XXXXXXXXXX.rs 16:1] connect mem_w1_1.clk, clk @[module-XXXXXXXXXX.rs 17:1] connect mem_w1_1.data, wdata @[module-XXXXXXXXXX.rs 18:1] connect mem_w1_1.mask, wmask @[module-XXXXXXXXXX.rs 19:1] "#, "/test/check_memory_of_enum/mem_body.mem": r"00 01 02 04 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f ", "/test/check_memory_of_enum/mem_tag.mem": r"00 10 10 10 01 01 01 01 01 01 01 01 01 01 01 01 ", }; #[rustfmt::skip] // work around https://github.com/rust-lang/rustfmt/issues/6161 assert_export_firrtl! { m => options: ExportOptions { simplify_enums: Some(SimplifyEnumsKind::ReplaceWithUInt), ..ExportOptions::default() }, "/test/check_memory_of_enum.fir": r#"FIRRTL version 3.2.0 circuit check_memory_of_enum: %[[ { "class": "firrtl.annotations.MemoryFileInlineAnnotation", "filename": "/test/check_memory_of_enum/mem.mem", "hexOrBinary": "b", "target": "~check_memory_of_enum|check_memory_of_enum>mem" } ]] type Ty0 = {addr: UInt<4>, en: UInt<1>, clk: Clock, flip data: UInt<10>} type Ty1 = {addr: UInt<4>, en: UInt<1>, clk: Clock, data: UInt<10>, mask: UInt<1>} module check_memory_of_enum: @[module-XXXXXXXXXX.rs 1:1] input raddr: UInt<8> @[module-XXXXXXXXXX.rs 2:1] output rdata: UInt<10> @[module-XXXXXXXXXX.rs 3:1] input waddr: UInt<8> @[module-XXXXXXXXXX.rs 4:1] input wdata: UInt<10> @[module-XXXXXXXXXX.rs 5:1] input wmask: UInt<1> @[module-XXXXXXXXXX.rs 6:1] input clk: Clock @[module-XXXXXXXXXX.rs 7:1] mem `mem`: @[module-XXXXXXXXXX.rs 8:1] data-type => UInt<10> depth => 16 read-latency => 0 write-latency => 1 read-under-write => old reader => r0 writer => w1 ; connect different types: ; lhs: UInt<4> ; rhs: UInt<8> connect `mem`.r0.addr, raddr @[module-XXXXXXXXXX.rs 10:1] connect `mem`.r0.en, UInt<1>(0h1) @[module-XXXXXXXXXX.rs 11:1] connect `mem`.r0.clk, clk @[module-XXXXXXXXXX.rs 12:1] connect rdata, `mem`.r0.data @[module-XXXXXXXXXX.rs 13:1] ; connect different types: ; lhs: UInt<4> ; rhs: UInt<8> connect `mem`.w1.addr, waddr @[module-XXXXXXXXXX.rs 15:1] connect `mem`.w1.en, UInt<1>(0h1) @[module-XXXXXXXXXX.rs 16:1] connect `mem`.w1.clk, clk @[module-XXXXXXXXXX.rs 17:1] connect `mem`.w1.data, wdata @[module-XXXXXXXXXX.rs 18:1] connect `mem`.w1.mask, wmask @[module-XXXXXXXXXX.rs 19:1] "#, "/test/check_memory_of_enum/mem.mem": r"0000000000 0000000110 0000001010 0000010010 0000010001 0000010101 0000011001 0000011101 0000100001 0000100101 0000101001 0000101101 0000110001 0000110101 0000111001 0000111101 ", }; } #[hdl_module(outline_generated)] pub fn check_memory_of_array_of_enum() { #[hdl] let raddr: UInt<8> = m.input(); #[hdl] let rdata: Array = m.output(); #[hdl] let waddr: UInt<8> = m.input(); #[hdl] let wdata: Array = m.input(); #[hdl] let wmask: Array = m.input(); #[hdl] let clk: Clock = m.input(); #[hdl] let mut mem = memory(); mem.depth(0x100); let read_port = mem.new_read_port(); connect_any(read_port.addr, raddr); connect(read_port.en, true); connect(read_port.clk, clk); connect(rdata, read_port.data); let write_port = mem.new_write_port(); connect_any(write_port.addr, waddr); connect(write_port.en, true); connect(write_port.clk, clk); connect(write_port.data, wdata); connect(write_port.mask, wmask); } #[test] fn test_memory_of_array_of_enum() { let _n = SourceLocation::normalize_files_for_tests(); let m = check_memory_of_array_of_enum(); dbg!(m); #[rustfmt::skip] // work around https://github.com/rust-lang/rustfmt/issues/6161 assert_export_firrtl! { m => options: ExportOptions { simplify_enums: None, ..ExportOptions::default() }, "/test/check_memory_of_array_of_enum.fir": r"FIRRTL version 3.2.0 circuit check_memory_of_array_of_enum: type Ty0 = {|A, B: UInt<8>, C: UInt<1>[3]|} type Ty1 = {addr: UInt<8>, en: UInt<1>, clk: Clock, flip data: Ty0[2]} type Ty2 = {addr: UInt<8>, en: UInt<1>, clk: Clock, data: Ty0[2], mask: UInt<1>[2]} type Ty3 = {addr: UInt<8>, en: UInt<1>, clk: Clock, flip data: UInt<10>[2]} type Ty4 = {addr: UInt<8>, en: UInt<1>, clk: Clock, data: UInt<10>[2], mask: UInt<1>[2]} module check_memory_of_array_of_enum: @[module-XXXXXXXXXX.rs 1:1] input raddr: UInt<8> @[module-XXXXXXXXXX.rs 2:1] output rdata: Ty0[2] @[module-XXXXXXXXXX.rs 3:1] input waddr: UInt<8> @[module-XXXXXXXXXX.rs 4:1] input wdata: Ty0[2] @[module-XXXXXXXXXX.rs 5:1] input wmask: UInt<1>[2] @[module-XXXXXXXXXX.rs 6:1] input clk: Clock @[module-XXXXXXXXXX.rs 7:1] mem `mem`: @[module-XXXXXXXXXX.rs 8:1] data-type => UInt<10>[2] depth => 256 read-latency => 0 write-latency => 1 read-under-write => old reader => r0 writer => w1 wire mem_r0: Ty1 @[module-XXXXXXXXXX.rs 9:1] wire mem_w1: Ty2 @[module-XXXXXXXXXX.rs 14:1] wire _cast_bits_to_enum_expr: Ty0 wire _cast_bits_to_enum_expr_body: UInt<8> connect _cast_bits_to_enum_expr_body, head(`mem`.r0.data[0], 8) when eq(UInt<2>(0), tail(`mem`.r0.data[0], 8)): connect _cast_bits_to_enum_expr, {|A, B: UInt<8>, C: UInt<1>[3]|}(A) else when eq(UInt<2>(1), tail(`mem`.r0.data[0], 8)): connect _cast_bits_to_enum_expr, {|A, B: UInt<8>, C: UInt<1>[3]|}(B, _cast_bits_to_enum_expr_body) else: wire _cast_bits_to_array_expr: UInt<1>[3] wire _cast_bits_to_array_expr_flattened: UInt<1>[3] connect _cast_bits_to_array_expr_flattened[0], bits(_cast_bits_to_enum_expr_body, 0, 0) connect _cast_bits_to_array_expr[0], _cast_bits_to_array_expr_flattened[0] connect _cast_bits_to_array_expr_flattened[1], bits(_cast_bits_to_enum_expr_body, 1, 1) connect _cast_bits_to_array_expr[1], _cast_bits_to_array_expr_flattened[1] connect _cast_bits_to_array_expr_flattened[2], bits(_cast_bits_to_enum_expr_body, 2, 2) connect _cast_bits_to_array_expr[2], _cast_bits_to_array_expr_flattened[2] connect _cast_bits_to_enum_expr, {|A, B: UInt<8>, C: UInt<1>[3]|}(C, _cast_bits_to_array_expr) connect mem_r0.data[0], _cast_bits_to_enum_expr @[module-XXXXXXXXXX.rs 9:1] wire _cast_bits_to_enum_expr_1: Ty0 wire _cast_bits_to_enum_expr_body_1: UInt<8> connect _cast_bits_to_enum_expr_body_1, head(`mem`.r0.data[1], 8) when eq(UInt<2>(0), tail(`mem`.r0.data[1], 8)): connect _cast_bits_to_enum_expr_1, {|A, B: UInt<8>, C: UInt<1>[3]|}(A) else when eq(UInt<2>(1), tail(`mem`.r0.data[1], 8)): connect _cast_bits_to_enum_expr_1, {|A, B: UInt<8>, C: UInt<1>[3]|}(B, _cast_bits_to_enum_expr_body_1) else: wire _cast_bits_to_array_expr_1: UInt<1>[3] wire _cast_bits_to_array_expr_flattened_1: UInt<1>[3] connect _cast_bits_to_array_expr_flattened_1[0], bits(_cast_bits_to_enum_expr_body_1, 0, 0) connect _cast_bits_to_array_expr_1[0], _cast_bits_to_array_expr_flattened_1[0] connect _cast_bits_to_array_expr_flattened_1[1], bits(_cast_bits_to_enum_expr_body_1, 1, 1) connect _cast_bits_to_array_expr_1[1], _cast_bits_to_array_expr_flattened_1[1] connect _cast_bits_to_array_expr_flattened_1[2], bits(_cast_bits_to_enum_expr_body_1, 2, 2) connect _cast_bits_to_array_expr_1[2], _cast_bits_to_array_expr_flattened_1[2] connect _cast_bits_to_enum_expr_1, {|A, B: UInt<8>, C: UInt<1>[3]|}(C, _cast_bits_to_array_expr_1) connect mem_r0.data[1], _cast_bits_to_enum_expr_1 @[module-XXXXXXXXXX.rs 9:1] wire _cast_enum_to_bits_expr: UInt<10> match mem_w1.data[0]: A: connect _cast_enum_to_bits_expr, UInt<10>(0) B(_cast_enum_to_bits_expr_B): connect _cast_enum_to_bits_expr, pad(cat(_cast_enum_to_bits_expr_B, UInt<2>(1)), 10) C(_cast_enum_to_bits_expr_C): wire _cast_array_to_bits_expr: UInt<1>[3] connect _cast_array_to_bits_expr[0], _cast_enum_to_bits_expr_C[0] connect _cast_array_to_bits_expr[1], _cast_enum_to_bits_expr_C[1] connect _cast_array_to_bits_expr[2], _cast_enum_to_bits_expr_C[2] wire _cast_to_bits_expr: UInt<3> connect _cast_to_bits_expr, cat(_cast_array_to_bits_expr[2], cat(_cast_array_to_bits_expr[1], _cast_array_to_bits_expr[0])) connect _cast_enum_to_bits_expr, pad(cat(_cast_to_bits_expr, UInt<2>(2)), 10) connect `mem`.w1.data[0], _cast_enum_to_bits_expr @[module-XXXXXXXXXX.rs 14:1] connect `mem`.w1.mask[0], mem_w1.mask[0] @[module-XXXXXXXXXX.rs 14:1] wire _cast_enum_to_bits_expr_1: UInt<10> match mem_w1.data[1]: A: connect _cast_enum_to_bits_expr_1, UInt<10>(0) B(_cast_enum_to_bits_expr_B_1): connect _cast_enum_to_bits_expr_1, pad(cat(_cast_enum_to_bits_expr_B_1, UInt<2>(1)), 10) C(_cast_enum_to_bits_expr_C_1): wire _cast_array_to_bits_expr_1: UInt<1>[3] connect _cast_array_to_bits_expr_1[0], _cast_enum_to_bits_expr_C_1[0] connect _cast_array_to_bits_expr_1[1], _cast_enum_to_bits_expr_C_1[1] connect _cast_array_to_bits_expr_1[2], _cast_enum_to_bits_expr_C_1[2] wire _cast_to_bits_expr_1: UInt<3> connect _cast_to_bits_expr_1, cat(_cast_array_to_bits_expr_1[2], cat(_cast_array_to_bits_expr_1[1], _cast_array_to_bits_expr_1[0])) connect _cast_enum_to_bits_expr_1, pad(cat(_cast_to_bits_expr_1, UInt<2>(2)), 10) connect `mem`.w1.data[1], _cast_enum_to_bits_expr_1 @[module-XXXXXXXXXX.rs 14:1] connect `mem`.w1.mask[1], mem_w1.mask[1] @[module-XXXXXXXXXX.rs 14:1] connect `mem`.r0.addr, mem_r0.addr @[module-XXXXXXXXXX.rs 9:1] connect `mem`.r0.clk, mem_r0.clk @[module-XXXXXXXXXX.rs 9:1] connect `mem`.r0.en, mem_r0.en @[module-XXXXXXXXXX.rs 9:1] connect `mem`.w1.addr, mem_w1.addr @[module-XXXXXXXXXX.rs 14:1] connect `mem`.w1.clk, mem_w1.clk @[module-XXXXXXXXXX.rs 14:1] connect `mem`.w1.en, mem_w1.en @[module-XXXXXXXXXX.rs 14:1] connect mem_r0.addr, raddr @[module-XXXXXXXXXX.rs 10:1] connect mem_r0.en, UInt<1>(0h1) @[module-XXXXXXXXXX.rs 11:1] connect mem_r0.clk, clk @[module-XXXXXXXXXX.rs 12:1] connect rdata, mem_r0.data @[module-XXXXXXXXXX.rs 13:1] connect mem_w1.addr, waddr @[module-XXXXXXXXXX.rs 15:1] connect mem_w1.en, UInt<1>(0h1) @[module-XXXXXXXXXX.rs 16:1] connect mem_w1.clk, clk @[module-XXXXXXXXXX.rs 17:1] connect mem_w1.data, wdata @[module-XXXXXXXXXX.rs 18:1] connect mem_w1.mask, wmask @[module-XXXXXXXXXX.rs 19:1] ", }; } #[hdl_module(outline_generated)] pub fn check_annotations() { m.annotate_module(CustomFirrtlAnnotation { class: "the.annotation.Example".intern(), additional_fields: json!({ "bar": "a nice module!", }) .try_into() .unwrap(), }); m.annotate_module(DocStringAnnotation { text: r"This module is used as a test that fayalite's firrtl backend properly emits annotations. Testing... " .intern(), }); #[hdl] let raddr: UInt<8> = m.input(); annotate(raddr, DontTouchAnnotation); #[hdl] let rdata: Array, 2> = m.output(); annotate( rdata, CustomFirrtlAnnotation { class: "the.annotation.ExampleClass".intern(), additional_fields: json!({ "foo": "bar", "baz": [0, 1, "a", "b"], }) .try_into() .unwrap(), }, ); #[hdl] let waddr: UInt<8> = m.input(); #[hdl] let wdata: Array, 2> = m.input(); #[hdl] let wmask: Array = m.input(); annotate( wmask[1], CustomFirrtlAnnotation { class: "some.annotation.Class".intern(), additional_fields: json!({ "baz": "second mask bit", }) .try_into() .unwrap(), }, ); #[hdl] let clk: Clock = m.input(); #[hdl] let mut mem = memory(); mem.depth(0x100); mem.annotate(CustomFirrtlAnnotation { class: "the.annotation.ExampleClass2".intern(), additional_fields: json!({ "bar": "foo", "baz": [0, 1, "a", "b"], }) .try_into() .unwrap(), }); let read_port = mem.new_read_port(); annotate( read_port, CustomFirrtlAnnotation { class: "the.annotation.ExampleClass3".intern(), additional_fields: json!({ "foo": "my read port", }) .try_into() .unwrap(), }, ); connect_any(read_port.addr, raddr); connect(read_port.en, true); connect(read_port.clk, clk); connect(rdata, read_port.data); let write_port = mem.new_write_port(); annotate( write_port.data[0], CustomFirrtlAnnotation { class: "some.annotation.Class".intern(), additional_fields: json!({ "baz": "first mask bit", }) .try_into() .unwrap(), }, ); connect_any(write_port.addr, waddr); connect(write_port.en, true); connect(write_port.clk, clk); connect(write_port.data, wdata); connect(write_port.mask, wmask); #[hdl_module(extern)] fn black_box1() { m.verilog_name("BlackBox1"); m.annotate_module(BlackBoxInlineAnnotation { path: "black_box1.v".intern(), text: r"(* blackbox *) module BlackBox1(); endmodule " .intern(), }); } #[hdl] let black_box1_instance = instance(black_box1()); annotate(black_box1_instance, DontTouchAnnotation); #[hdl_module(extern)] fn black_box2() { m.verilog_name("BlackBox2"); m.annotate_module(BlackBoxPathAnnotation { path: "black_box2.v".intern(), }); } #[hdl] let black_box2_instance = instance(black_box2()); annotate(black_box2_instance, DontTouchAnnotation); #[hdl] let a_wire: (SInt<1>, Bool) = wire(); annotate( a_wire.1, SVAttributeAnnotation { text: "custom_sv_attr = \"abc\"".intern(), }, ); connect(a_wire, (0_hdl_i1, false)); } #[test] fn test_annotations() { let _n = SourceLocation::normalize_files_for_tests(); let m = check_annotations(); dbg!(m); #[rustfmt::skip] // work around https://github.com/rust-lang/rustfmt/issues/6161 assert_export_firrtl! { m => "/test/check_annotations.fir": r#"FIRRTL version 3.2.0 circuit check_annotations: %[[ { "class": "the.annotation.Example", "bar": "a nice module!", "target": "~check_annotations|check_annotations" }, { "class": "firrtl.DocStringAnnotation", "description": "This module is used as a test that fayalite's firrtl\nbackend properly emits annotations.\n\nTesting...\n", "target": "~check_annotations|check_annotations" }, { "class": "firrtl.transforms.DontTouchAnnotation", "target": "~check_annotations|check_annotations>raddr" }, { "class": "the.annotation.ExampleClass", "foo": "bar", "baz": [ 0, 1, "a", "b" ], "target": "~check_annotations|check_annotations>rdata" }, { "class": "some.annotation.Class", "baz": "second mask bit", "target": "~check_annotations|check_annotations>wmask[1]" }, { "class": "the.annotation.ExampleClass2", "bar": "foo", "baz": [ 0, 1, "a", "b" ], "target": "~check_annotations|check_annotations>mem" }, { "class": "the.annotation.ExampleClass3", "foo": "my read port", "target": "~check_annotations|check_annotations>mem.r0" }, { "class": "some.annotation.Class", "baz": "first mask bit", "target": "~check_annotations|check_annotations>mem.w1.data[0]" }, { "class": "firrtl.transforms.DontTouchAnnotation", "target": "~check_annotations|check_annotations>black_box1_instance" }, { "class": "firrtl.transforms.DontTouchAnnotation", "target": "~check_annotations|check_annotations>black_box2_instance" }, { "class": "firrtl.AttributeAnnotation", "description": "custom_sv_attr = \"abc\"", "target": "~check_annotations|check_annotations>a_wire.1" }, { "class": "firrtl.transforms.BlackBoxInlineAnno", "name": "black_box1.v", "text": "(* blackbox *)\nmodule BlackBox1();\nendmodule\n", "target": "~check_annotations|black_box1" }, { "class": "firrtl.transforms.BlackBoxPathAnno", "path": "black_box2.v", "target": "~check_annotations|black_box2" } ]] type Ty0 = {addr: UInt<8>, en: UInt<1>, clk: Clock, data: UInt<4>[2], mask: UInt<1>[2]} type Ty1 = {addr: UInt<8>, en: UInt<1>, clk: Clock, flip data: UInt<4>[2]} type Ty2 = {`0`: SInt<1>, `1`: UInt<1>} module check_annotations: @[module-XXXXXXXXXX.rs 1:1] input raddr: UInt<8> @[module-XXXXXXXXXX.rs 2:1] output rdata: UInt<4>[2] @[module-XXXXXXXXXX.rs 3:1] input waddr: UInt<8> @[module-XXXXXXXXXX.rs 4:1] input wdata: UInt<4>[2] @[module-XXXXXXXXXX.rs 5:1] input wmask: UInt<1>[2] @[module-XXXXXXXXXX.rs 6:1] input clk: Clock @[module-XXXXXXXXXX.rs 7:1] mem `mem`: @[module-XXXXXXXXXX.rs 8:1] data-type => UInt<4>[2] depth => 256 read-latency => 0 write-latency => 1 read-under-write => old reader => r0 writer => w1 connect `mem`.r0.addr, raddr @[module-XXXXXXXXXX.rs 10:1] connect `mem`.r0.en, UInt<1>(0h1) @[module-XXXXXXXXXX.rs 11:1] connect `mem`.r0.clk, clk @[module-XXXXXXXXXX.rs 12:1] connect rdata, `mem`.r0.data @[module-XXXXXXXXXX.rs 13:1] connect `mem`.w1.addr, waddr @[module-XXXXXXXXXX.rs 15:1] connect `mem`.w1.en, UInt<1>(0h1) @[module-XXXXXXXXXX.rs 16:1] connect `mem`.w1.clk, clk @[module-XXXXXXXXXX.rs 17:1] connect `mem`.w1.data, wdata @[module-XXXXXXXXXX.rs 18:1] connect `mem`.w1.mask, wmask @[module-XXXXXXXXXX.rs 19:1] inst black_box1_instance of black_box1 @[module-XXXXXXXXXX.rs 21:1] inst black_box2_instance of black_box2 @[module-XXXXXXXXXX.rs 23:1] wire a_wire: Ty2 @[module-XXXXXXXXXX.rs 24:1] wire _bundle_literal_expr: Ty2 connect _bundle_literal_expr.`0`, SInt<1>(0h0) connect _bundle_literal_expr.`1`, UInt<1>(0h0) connect a_wire, _bundle_literal_expr @[module-XXXXXXXXXX.rs 25:1] extmodule black_box1: @[module-XXXXXXXXXX.rs 20:1] defname = BlackBox1 extmodule black_box2: @[module-XXXXXXXXXX.rs 22:1] defname = BlackBox2 "#, }; } #[hdl_module(outline_generated)] pub fn check_uninit(ty: T) { #[hdl] let o: T = m.output(ty); connect(o, ty.uninit()); } #[test] fn test_uninit() { let _n = SourceLocation::normalize_files_for_tests(); let m = check_uninit((UInt[3], SInt[5], Clock)); dbg!(m); #[rustfmt::skip] // work around https://github.com/rust-lang/rustfmt/issues/6161 assert_export_firrtl! { m => "/test/check_uninit.fir": r"FIRRTL version 3.2.0 circuit check_uninit: type Ty0 = {`0`: UInt<3>, `1`: SInt<5>, `2`: Clock} module check_uninit: @[module-XXXXXXXXXX.rs 1:1] output o: Ty0 @[module-XXXXXXXXXX.rs 2:1] wire _uninit_expr: Ty0 invalidate _uninit_expr connect o, _uninit_expr @[module-XXXXXXXXXX.rs 3:1] ", }; let m = check_uninit(Array[HdlOption[()]][3]); dbg!(m); #[rustfmt::skip] // work around https://github.com/rust-lang/rustfmt/issues/6161 assert_export_firrtl! { m => options: ExportOptions { simplify_enums: None, ..ExportOptions::default() }, "/test/check_uninit.fir": r"FIRRTL version 3.2.0 circuit check_uninit: type Ty0 = {} type Ty1 = {|HdlNone, HdlSome: Ty0|} module check_uninit: @[module-XXXXXXXXXX.rs 1:1] output o: Ty1[3] @[module-XXXXXXXXXX.rs 2:1] wire _uninit_expr: Ty1[3] invalidate _uninit_expr connect o, _uninit_expr @[module-XXXXXXXXXX.rs 3:1] ", }; } #[hdl_module(outline_generated)] pub fn check_formal() { #[hdl] let clk: Clock = m.input(); #[hdl] let en1: Bool = m.input(); #[hdl] let en2: Bool = m.input(); #[hdl] let en3: Bool = m.input(); #[hdl] let pred1: Bool = m.input(); #[hdl] let pred2: Bool = m.input(); #[hdl] let pred3: Bool = m.input(); hdl_assert_with_enable(clk, pred1, en1, "en check 1"); hdl_assume_with_enable(clk, pred2, en2, "en check 2"); hdl_cover_with_enable(clk, pred3, en3, "en check 3"); hdl_assert(clk, pred1, "check 1"); hdl_assume(clk, pred2, "check 2"); hdl_cover(clk, pred3, "check 3"); } #[test] fn test_formal() { let _n = SourceLocation::normalize_files_for_tests(); let m = check_formal(); dbg!(m); #[rustfmt::skip] // work around https://github.com/rust-lang/rustfmt/issues/6161 assert_export_firrtl! { m => "/test/check_formal.fir": r#"FIRRTL version 3.2.0 circuit check_formal: %[[ { "class": "firrtl.transforms.BlackBoxInlineAnno", "name": "fayalite_formal_reset.v", "text": "module __fayalite_formal_reset(output rst);\n assign rst = $initstate;\nendmodule\n", "target": "~check_formal|formal_reset" } ]] type Ty0 = {rst: UInt<1>} module check_formal: @[module-XXXXXXXXXX.rs 1:1] input clk: Clock @[module-XXXXXXXXXX.rs 2:1] input en1: UInt<1> @[module-XXXXXXXXXX.rs 3:1] input en2: UInt<1> @[module-XXXXXXXXXX.rs 4:1] input en3: UInt<1> @[module-XXXXXXXXXX.rs 5:1] input pred1: UInt<1> @[module-XXXXXXXXXX.rs 6:1] input pred2: UInt<1> @[module-XXXXXXXXXX.rs 7:1] input pred3: UInt<1> @[module-XXXXXXXXXX.rs 8:1] inst formal_reset of formal_reset @[formal.rs 185:24] assert(clk, pred1, and(en1, not(formal_reset.rst)), "en check 1") @[module-XXXXXXXXXX.rs 9:1] inst formal_reset_1 of formal_reset @[formal.rs 185:24] assume(clk, pred2, and(en2, not(formal_reset_1.rst)), "en check 2") @[module-XXXXXXXXXX.rs 10:1] inst formal_reset_2 of formal_reset @[formal.rs 185:24] cover(clk, pred3, and(en3, not(formal_reset_2.rst)), "en check 3") @[module-XXXXXXXXXX.rs 11:1] inst formal_reset_3 of formal_reset @[formal.rs 185:24] assert(clk, pred1, and(UInt<1>(0h1), not(formal_reset_3.rst)), "check 1") @[module-XXXXXXXXXX.rs 12:1] inst formal_reset_4 of formal_reset @[formal.rs 185:24] assume(clk, pred2, and(UInt<1>(0h1), not(formal_reset_4.rst)), "check 2") @[module-XXXXXXXXXX.rs 13:1] inst formal_reset_5 of formal_reset @[formal.rs 185:24] cover(clk, pred3, and(UInt<1>(0h1), not(formal_reset_5.rst)), "check 3") @[module-XXXXXXXXXX.rs 14:1] extmodule formal_reset: @[formal.rs 169:5] output rst: UInt<1> @[formal.rs 172:32] defname = __fayalite_formal_reset "#, }; } #[hdl] pub enum OneOfThree { A(A), B(B), C(C), } #[hdl_module(outline_generated)] pub fn check_enum_connect_any() { #[hdl] let swap: Bool = m.input(); #[hdl] let i1: OneOfThree, HdlOption>, HdlOption<()>> = m.input(); #[hdl] let i2: OneOfThree, HdlOption>, HdlOption<()>> = m.input(); #[hdl] let o1: OneOfThree, HdlOption>, HdlOption<()>> = m.output(); #[hdl] let o2: OneOfThree, HdlOption>, HdlOption<()>> = m.output(); #[hdl] if swap { connect_any(o1, i2); connect_any(o2, i1); } else { connect_any(o1, i1); connect_any(o2, i2); } } #[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 => options: ExportOptions { simplify_enums: None, ..ExportOptions::default() }, "/test/check_enum_connect_any.fir": r"FIRRTL version 3.2.0 circuit check_enum_connect_any: type Ty0 = {|HdlNone, HdlSome: SInt<1>|} type Ty1 = {} type Ty2 = {|HdlNone, HdlSome: Ty1|} type Ty3 = {|A: UInt<1>, B: Ty0, C: Ty2|} type Ty4 = {|HdlNone, HdlSome: SInt<2>|} type Ty5 = {|A: UInt<2>, B: Ty4, C: Ty2|} module check_enum_connect_any: @[module-XXXXXXXXXX.rs 1:1] input swap: UInt<1> @[module-XXXXXXXXXX.rs 2:1] input i1: Ty3 @[module-XXXXXXXXXX.rs 3:1] input i2: Ty5 @[module-XXXXXXXXXX.rs 4:1] output o1: Ty3 @[module-XXXXXXXXXX.rs 5:1] output o2: Ty5 @[module-XXXXXXXXXX.rs 6:1] when swap: @[module-XXXXXXXXXX.rs 7:1] ; connect different types: ; lhs: Enum {A(UInt<1>), B(Enum {HdlNone, HdlSome(SInt<1>)}), C(Enum {HdlNone, HdlSome(Bundle {})})} ; rhs: Enum {A(UInt<2>), B(Enum {HdlNone, HdlSome(SInt<2>)}), C(Enum {HdlNone, HdlSome(Bundle {})})} connect o1, i2 @[module-XXXXXXXXXX.rs 8:1] ; connect different types: ; lhs: Enum {A(UInt<2>), B(Enum {HdlNone, HdlSome(SInt<2>)}), C(Enum {HdlNone, HdlSome(Bundle {})})} ; rhs: Enum {A(UInt<1>), B(Enum {HdlNone, HdlSome(SInt<1>)}), C(Enum {HdlNone, HdlSome(Bundle {})})} connect o2, i1 @[module-XXXXXXXXXX.rs 9:1] else: connect o1, i1 @[module-XXXXXXXXXX.rs 10:1] connect o2, i2 @[module-XXXXXXXXXX.rs 11:1] ", }; #[rustfmt::skip] // work around https://github.com/rust-lang/rustfmt/issues/6161 assert_export_firrtl! { m => options: ExportOptions { simplify_enums: Some(SimplifyEnumsKind::SimplifyToEnumsWithNoBody), ..ExportOptions::default() }, "/test/check_enum_connect_any.fir": r"FIRRTL version 3.2.0 circuit check_enum_connect_any: type Ty0 = {|A, B, C|} type Ty1 = {tag: Ty0, body: UInt<2>} type Ty2 = {tag: Ty0, body: UInt<3>} type Ty3 = {|HdlNone, HdlSome|} type Ty4 = {tag: Ty3, body: UInt<1>} type Ty5 = {tag: Ty3, body: UInt<2>} type Ty6 = {tag: UInt<1>, body: UInt<2>} type Ty7 = {tag: UInt<1>, body: UInt<1>} type Ty8 = {tag: Ty3, body: UInt<0>} type Ty9 = {tag: UInt<1>, body: UInt<0>} module check_enum_connect_any: @[module-XXXXXXXXXX.rs 1:1] input swap: UInt<1> @[module-XXXXXXXXXX.rs 2:1] input i1: Ty1 @[module-XXXXXXXXXX.rs 3:1] input i2: Ty2 @[module-XXXXXXXXXX.rs 4:1] output o1: Ty1 @[module-XXXXXXXXXX.rs 5:1] output o2: Ty2 @[module-XXXXXXXXXX.rs 6:1] when swap: @[module-XXXXXXXXXX.rs 7:1] match i2.tag: @[module-XXXXXXXXXX.rs 8:1] A: wire __connect_variant_body: UInt<1> @[module-XXXXXXXXXX.rs 8:1] ; connect different types: ; lhs: UInt<1> ; rhs: UInt<2> connect __connect_variant_body, bits(i2.body, 1, 0) @[module-XXXXXXXXXX.rs 8:1] wire _bundle_literal_expr: Ty1 connect _bundle_literal_expr.tag, {|A, B, C|}(A) connect _bundle_literal_expr.body, pad(__connect_variant_body, 2) connect o1, _bundle_literal_expr @[module-XXXXXXXXXX.rs 8:1] B: wire __connect_variant_body_1: Ty4 @[module-XXXXXXXXXX.rs 8:1] wire _cast_bits_to_bundle_expr: Ty5 wire _cast_bits_to_bundle_expr_flattened: Ty6 connect _cast_bits_to_bundle_expr_flattened.tag, bits(bits(i2.body, 2, 0), 0, 0) wire _cast_bits_to_enum_expr: Ty3 when eq(UInt<1>(0), tail(_cast_bits_to_bundle_expr_flattened.tag, 0)): connect _cast_bits_to_enum_expr, {|HdlNone, HdlSome|}(HdlNone) else: connect _cast_bits_to_enum_expr, {|HdlNone, HdlSome|}(HdlSome) connect _cast_bits_to_bundle_expr.tag, _cast_bits_to_enum_expr connect _cast_bits_to_bundle_expr_flattened.body, bits(bits(i2.body, 2, 0), 2, 1) connect _cast_bits_to_bundle_expr.body, _cast_bits_to_bundle_expr_flattened.body match _cast_bits_to_bundle_expr.tag: @[module-XXXXXXXXXX.rs 8:1] HdlNone: wire _bundle_literal_expr_1: Ty4 connect _bundle_literal_expr_1.tag, {|HdlNone, HdlSome|}(HdlNone) connect _bundle_literal_expr_1.body, UInt<1>(0h0) connect __connect_variant_body_1, _bundle_literal_expr_1 @[module-XXXXXXXXXX.rs 8:1] HdlSome: wire __connect_variant_body_2: SInt<1> @[module-XXXXXXXXXX.rs 8:1] wire _cast_bits_to_bundle_expr_1: Ty5 wire _cast_bits_to_bundle_expr_flattened_1: Ty6 connect _cast_bits_to_bundle_expr_flattened_1.tag, bits(bits(i2.body, 2, 0), 0, 0) wire _cast_bits_to_enum_expr_1: Ty3 when eq(UInt<1>(0), tail(_cast_bits_to_bundle_expr_flattened_1.tag, 0)): connect _cast_bits_to_enum_expr_1, {|HdlNone, HdlSome|}(HdlNone) else: connect _cast_bits_to_enum_expr_1, {|HdlNone, HdlSome|}(HdlSome) connect _cast_bits_to_bundle_expr_1.tag, _cast_bits_to_enum_expr_1 connect _cast_bits_to_bundle_expr_flattened_1.body, bits(bits(i2.body, 2, 0), 2, 1) connect _cast_bits_to_bundle_expr_1.body, _cast_bits_to_bundle_expr_flattened_1.body ; connect different types: ; lhs: SInt<1> ; rhs: SInt<2> connect __connect_variant_body_2, asSInt(bits(_cast_bits_to_bundle_expr_1.body, 1, 0)) @[module-XXXXXXXXXX.rs 8:1] wire _bundle_literal_expr_2: Ty4 connect _bundle_literal_expr_2.tag, {|HdlNone, HdlSome|}(HdlSome) connect _bundle_literal_expr_2.body, asUInt(__connect_variant_body_2) connect __connect_variant_body_1, _bundle_literal_expr_2 @[module-XXXXXXXXXX.rs 8:1] wire _bundle_literal_expr_3: Ty1 connect _bundle_literal_expr_3.tag, {|A, B, C|}(B) wire _cast_bundle_to_bits_expr: Ty7 wire _cast_enum_to_bits_expr: UInt<1> match __connect_variant_body_1.tag: HdlNone: connect _cast_enum_to_bits_expr, UInt<1>(0) HdlSome: connect _cast_enum_to_bits_expr, UInt<1>(1) connect _cast_bundle_to_bits_expr.tag, _cast_enum_to_bits_expr connect _cast_bundle_to_bits_expr.body, __connect_variant_body_1.body wire _cast_to_bits_expr: UInt<2> connect _cast_to_bits_expr, cat(_cast_bundle_to_bits_expr.body, _cast_bundle_to_bits_expr.tag) connect _bundle_literal_expr_3.body, _cast_to_bits_expr connect o1, _bundle_literal_expr_3 @[module-XXXXXXXXXX.rs 8:1] C: wire __connect_variant_body_3: Ty8 @[module-XXXXXXXXXX.rs 8:1] wire _cast_bits_to_bundle_expr_2: Ty8 wire _cast_bits_to_bundle_expr_flattened_2: Ty9 connect _cast_bits_to_bundle_expr_flattened_2.tag, bits(bits(i2.body, 0, 0), 0, 0) wire _cast_bits_to_enum_expr_2: Ty3 when eq(UInt<1>(0), tail(_cast_bits_to_bundle_expr_flattened_2.tag, 0)): connect _cast_bits_to_enum_expr_2, {|HdlNone, HdlSome|}(HdlNone) else: connect _cast_bits_to_enum_expr_2, {|HdlNone, HdlSome|}(HdlSome) connect _cast_bits_to_bundle_expr_2.tag, _cast_bits_to_enum_expr_2 connect _cast_bits_to_bundle_expr_flattened_2.body, UInt<0>(0) connect _cast_bits_to_bundle_expr_2.body, _cast_bits_to_bundle_expr_flattened_2.body connect __connect_variant_body_3, _cast_bits_to_bundle_expr_2 @[module-XXXXXXXXXX.rs 8:1] wire _bundle_literal_expr_4: Ty1 connect _bundle_literal_expr_4.tag, {|A, B, C|}(C) wire _cast_bundle_to_bits_expr_1: Ty9 wire _cast_enum_to_bits_expr_1: UInt<1> match __connect_variant_body_3.tag: HdlNone: connect _cast_enum_to_bits_expr_1, UInt<1>(0) HdlSome: connect _cast_enum_to_bits_expr_1, UInt<1>(1) connect _cast_bundle_to_bits_expr_1.tag, _cast_enum_to_bits_expr_1 connect _cast_bundle_to_bits_expr_1.body, __connect_variant_body_3.body wire _cast_to_bits_expr_1: UInt<1> connect _cast_to_bits_expr_1, cat(_cast_bundle_to_bits_expr_1.body, _cast_bundle_to_bits_expr_1.tag) connect _bundle_literal_expr_4.body, pad(_cast_to_bits_expr_1, 2) connect o1, _bundle_literal_expr_4 @[module-XXXXXXXXXX.rs 8:1] match i1.tag: @[module-XXXXXXXXXX.rs 9:1] A: wire __connect_variant_body_4: UInt<2> @[module-XXXXXXXXXX.rs 9:1] ; connect different types: ; lhs: UInt<2> ; rhs: UInt<1> connect __connect_variant_body_4, bits(i1.body, 0, 0) @[module-XXXXXXXXXX.rs 9:1] wire _bundle_literal_expr_5: Ty2 connect _bundle_literal_expr_5.tag, {|A, B, C|}(A) connect _bundle_literal_expr_5.body, pad(__connect_variant_body_4, 3) connect o2, _bundle_literal_expr_5 @[module-XXXXXXXXXX.rs 9:1] B: wire __connect_variant_body_5: Ty5 @[module-XXXXXXXXXX.rs 9:1] wire _cast_bits_to_bundle_expr_3: Ty4 wire _cast_bits_to_bundle_expr_flattened_3: Ty7 connect _cast_bits_to_bundle_expr_flattened_3.tag, bits(bits(i1.body, 1, 0), 0, 0) wire _cast_bits_to_enum_expr_3: Ty3 when eq(UInt<1>(0), tail(_cast_bits_to_bundle_expr_flattened_3.tag, 0)): connect _cast_bits_to_enum_expr_3, {|HdlNone, HdlSome|}(HdlNone) else: connect _cast_bits_to_enum_expr_3, {|HdlNone, HdlSome|}(HdlSome) connect _cast_bits_to_bundle_expr_3.tag, _cast_bits_to_enum_expr_3 connect _cast_bits_to_bundle_expr_flattened_3.body, bits(bits(i1.body, 1, 0), 1, 1) connect _cast_bits_to_bundle_expr_3.body, _cast_bits_to_bundle_expr_flattened_3.body match _cast_bits_to_bundle_expr_3.tag: @[module-XXXXXXXXXX.rs 9:1] HdlNone: wire _bundle_literal_expr_6: Ty5 connect _bundle_literal_expr_6.tag, {|HdlNone, HdlSome|}(HdlNone) connect _bundle_literal_expr_6.body, UInt<2>(0h0) connect __connect_variant_body_5, _bundle_literal_expr_6 @[module-XXXXXXXXXX.rs 9:1] HdlSome: wire __connect_variant_body_6: SInt<2> @[module-XXXXXXXXXX.rs 9:1] wire _cast_bits_to_bundle_expr_4: Ty4 wire _cast_bits_to_bundle_expr_flattened_4: Ty7 connect _cast_bits_to_bundle_expr_flattened_4.tag, bits(bits(i1.body, 1, 0), 0, 0) wire _cast_bits_to_enum_expr_4: Ty3 when eq(UInt<1>(0), tail(_cast_bits_to_bundle_expr_flattened_4.tag, 0)): connect _cast_bits_to_enum_expr_4, {|HdlNone, HdlSome|}(HdlNone) else: connect _cast_bits_to_enum_expr_4, {|HdlNone, HdlSome|}(HdlSome) connect _cast_bits_to_bundle_expr_4.tag, _cast_bits_to_enum_expr_4 connect _cast_bits_to_bundle_expr_flattened_4.body, bits(bits(i1.body, 1, 0), 1, 1) connect _cast_bits_to_bundle_expr_4.body, _cast_bits_to_bundle_expr_flattened_4.body ; connect different types: ; lhs: SInt<2> ; rhs: SInt<1> connect __connect_variant_body_6, asSInt(bits(_cast_bits_to_bundle_expr_4.body, 0, 0)) @[module-XXXXXXXXXX.rs 9:1] wire _bundle_literal_expr_7: Ty5 connect _bundle_literal_expr_7.tag, {|HdlNone, HdlSome|}(HdlSome) connect _bundle_literal_expr_7.body, asUInt(__connect_variant_body_6) connect __connect_variant_body_5, _bundle_literal_expr_7 @[module-XXXXXXXXXX.rs 9:1] wire _bundle_literal_expr_8: Ty2 connect _bundle_literal_expr_8.tag, {|A, B, C|}(B) wire _cast_bundle_to_bits_expr_2: Ty6 wire _cast_enum_to_bits_expr_2: UInt<1> match __connect_variant_body_5.tag: HdlNone: connect _cast_enum_to_bits_expr_2, UInt<1>(0) HdlSome: connect _cast_enum_to_bits_expr_2, UInt<1>(1) connect _cast_bundle_to_bits_expr_2.tag, _cast_enum_to_bits_expr_2 connect _cast_bundle_to_bits_expr_2.body, __connect_variant_body_5.body wire _cast_to_bits_expr_2: UInt<3> connect _cast_to_bits_expr_2, cat(_cast_bundle_to_bits_expr_2.body, _cast_bundle_to_bits_expr_2.tag) connect _bundle_literal_expr_8.body, _cast_to_bits_expr_2 connect o2, _bundle_literal_expr_8 @[module-XXXXXXXXXX.rs 9:1] C: wire __connect_variant_body_7: Ty8 @[module-XXXXXXXXXX.rs 9:1] wire _cast_bits_to_bundle_expr_5: Ty8 wire _cast_bits_to_bundle_expr_flattened_5: Ty9 connect _cast_bits_to_bundle_expr_flattened_5.tag, bits(bits(i1.body, 0, 0), 0, 0) wire _cast_bits_to_enum_expr_5: Ty3 when eq(UInt<1>(0), tail(_cast_bits_to_bundle_expr_flattened_5.tag, 0)): connect _cast_bits_to_enum_expr_5, {|HdlNone, HdlSome|}(HdlNone) else: connect _cast_bits_to_enum_expr_5, {|HdlNone, HdlSome|}(HdlSome) connect _cast_bits_to_bundle_expr_5.tag, _cast_bits_to_enum_expr_5 connect _cast_bits_to_bundle_expr_flattened_5.body, UInt<0>(0) connect _cast_bits_to_bundle_expr_5.body, _cast_bits_to_bundle_expr_flattened_5.body connect __connect_variant_body_7, _cast_bits_to_bundle_expr_5 @[module-XXXXXXXXXX.rs 9:1] wire _bundle_literal_expr_9: Ty2 connect _bundle_literal_expr_9.tag, {|A, B, C|}(C) wire _cast_bundle_to_bits_expr_3: Ty9 wire _cast_enum_to_bits_expr_3: UInt<1> match __connect_variant_body_7.tag: HdlNone: connect _cast_enum_to_bits_expr_3, UInt<1>(0) HdlSome: connect _cast_enum_to_bits_expr_3, UInt<1>(1) connect _cast_bundle_to_bits_expr_3.tag, _cast_enum_to_bits_expr_3 connect _cast_bundle_to_bits_expr_3.body, __connect_variant_body_7.body wire _cast_to_bits_expr_3: UInt<1> connect _cast_to_bits_expr_3, cat(_cast_bundle_to_bits_expr_3.body, _cast_bundle_to_bits_expr_3.tag) connect _bundle_literal_expr_9.body, pad(_cast_to_bits_expr_3, 3) connect o2, _bundle_literal_expr_9 @[module-XXXXXXXXXX.rs 9:1] else: connect o1, i1 @[module-XXXXXXXXXX.rs 10:1] connect o2, i2 @[module-XXXXXXXXXX.rs 11:1] ", }; #[rustfmt::skip] // work around https://github.com/rust-lang/rustfmt/issues/6161 assert_export_firrtl! { m => options: ExportOptions { simplify_enums: Some(SimplifyEnumsKind::ReplaceWithBundleOfUInts), ..ExportOptions::default() }, "/test/check_enum_connect_any.fir": r"FIRRTL version 3.2.0 circuit check_enum_connect_any: type Ty0 = {tag: UInt<2>, body: UInt<2>} type Ty1 = {tag: UInt<2>, body: UInt<3>} type Ty2 = {tag: UInt<1>, body: UInt<1>} type Ty3 = {tag: UInt<1>, body: UInt<2>} type Ty4 = {tag: UInt<1>, body: UInt<0>} module check_enum_connect_any: @[module-XXXXXXXXXX.rs 1:1] input swap: UInt<1> @[module-XXXXXXXXXX.rs 2:1] input i1: Ty0 @[module-XXXXXXXXXX.rs 3:1] input i2: Ty1 @[module-XXXXXXXXXX.rs 4:1] output o1: Ty0 @[module-XXXXXXXXXX.rs 5:1] output o2: Ty1 @[module-XXXXXXXXXX.rs 6:1] when swap: @[module-XXXXXXXXXX.rs 7:1] when eq(i2.tag, UInt<2>(0h0)): @[module-XXXXXXXXXX.rs 8:1] wire __connect_variant_body: UInt<1> @[module-XXXXXXXXXX.rs 8:1] ; connect different types: ; lhs: UInt<1> ; rhs: UInt<2> connect __connect_variant_body, bits(i2.body, 1, 0) @[module-XXXXXXXXXX.rs 8:1] wire _bundle_literal_expr: Ty0 connect _bundle_literal_expr.tag, UInt<2>(0h0) connect _bundle_literal_expr.body, pad(__connect_variant_body, 2) connect o1, _bundle_literal_expr @[module-XXXXXXXXXX.rs 8:1] else when eq(i2.tag, UInt<2>(0h1)): @[module-XXXXXXXXXX.rs 8:1] wire __connect_variant_body_1: Ty2 @[module-XXXXXXXXXX.rs 8:1] wire _cast_bits_to_bundle_expr: Ty3 wire _cast_bits_to_bundle_expr_flattened: Ty3 connect _cast_bits_to_bundle_expr_flattened.tag, bits(bits(i2.body, 2, 0), 0, 0) connect _cast_bits_to_bundle_expr.tag, _cast_bits_to_bundle_expr_flattened.tag connect _cast_bits_to_bundle_expr_flattened.body, bits(bits(i2.body, 2, 0), 2, 1) connect _cast_bits_to_bundle_expr.body, _cast_bits_to_bundle_expr_flattened.body when eq(_cast_bits_to_bundle_expr.tag, UInt<1>(0h0)): @[module-XXXXXXXXXX.rs 8:1] wire _bundle_literal_expr_1: Ty2 connect _bundle_literal_expr_1.tag, UInt<1>(0h0) connect _bundle_literal_expr_1.body, UInt<1>(0h0) connect __connect_variant_body_1, _bundle_literal_expr_1 @[module-XXXXXXXXXX.rs 8:1] else: wire __connect_variant_body_2: SInt<1> @[module-XXXXXXXXXX.rs 8:1] wire _cast_bits_to_bundle_expr_1: Ty3 wire _cast_bits_to_bundle_expr_flattened_1: Ty3 connect _cast_bits_to_bundle_expr_flattened_1.tag, bits(bits(i2.body, 2, 0), 0, 0) connect _cast_bits_to_bundle_expr_1.tag, _cast_bits_to_bundle_expr_flattened_1.tag connect _cast_bits_to_bundle_expr_flattened_1.body, bits(bits(i2.body, 2, 0), 2, 1) connect _cast_bits_to_bundle_expr_1.body, _cast_bits_to_bundle_expr_flattened_1.body ; connect different types: ; lhs: SInt<1> ; rhs: SInt<2> connect __connect_variant_body_2, asSInt(bits(_cast_bits_to_bundle_expr_1.body, 1, 0)) @[module-XXXXXXXXXX.rs 8:1] wire _bundle_literal_expr_2: Ty2 connect _bundle_literal_expr_2.tag, UInt<1>(0h1) connect _bundle_literal_expr_2.body, asUInt(__connect_variant_body_2) connect __connect_variant_body_1, _bundle_literal_expr_2 @[module-XXXXXXXXXX.rs 8:1] wire _bundle_literal_expr_3: Ty0 connect _bundle_literal_expr_3.tag, UInt<2>(0h1) wire _cast_bundle_to_bits_expr: Ty2 connect _cast_bundle_to_bits_expr.tag, __connect_variant_body_1.tag connect _cast_bundle_to_bits_expr.body, __connect_variant_body_1.body wire _cast_to_bits_expr: UInt<2> connect _cast_to_bits_expr, cat(_cast_bundle_to_bits_expr.body, _cast_bundle_to_bits_expr.tag) connect _bundle_literal_expr_3.body, _cast_to_bits_expr connect o1, _bundle_literal_expr_3 @[module-XXXXXXXXXX.rs 8:1] else: wire __connect_variant_body_3: Ty4 @[module-XXXXXXXXXX.rs 8:1] wire _cast_bits_to_bundle_expr_2: Ty4 wire _cast_bits_to_bundle_expr_flattened_2: Ty4 connect _cast_bits_to_bundle_expr_flattened_2.tag, bits(bits(i2.body, 0, 0), 0, 0) connect _cast_bits_to_bundle_expr_2.tag, _cast_bits_to_bundle_expr_flattened_2.tag connect _cast_bits_to_bundle_expr_flattened_2.body, UInt<0>(0) connect _cast_bits_to_bundle_expr_2.body, _cast_bits_to_bundle_expr_flattened_2.body connect __connect_variant_body_3, _cast_bits_to_bundle_expr_2 @[module-XXXXXXXXXX.rs 8:1] wire _bundle_literal_expr_4: Ty0 connect _bundle_literal_expr_4.tag, UInt<2>(0h2) wire _cast_bundle_to_bits_expr_1: Ty4 connect _cast_bundle_to_bits_expr_1.tag, __connect_variant_body_3.tag connect _cast_bundle_to_bits_expr_1.body, __connect_variant_body_3.body wire _cast_to_bits_expr_1: UInt<1> connect _cast_to_bits_expr_1, cat(_cast_bundle_to_bits_expr_1.body, _cast_bundle_to_bits_expr_1.tag) connect _bundle_literal_expr_4.body, pad(_cast_to_bits_expr_1, 2) connect o1, _bundle_literal_expr_4 @[module-XXXXXXXXXX.rs 8:1] when eq(i1.tag, UInt<2>(0h0)): @[module-XXXXXXXXXX.rs 9:1] wire __connect_variant_body_4: UInt<2> @[module-XXXXXXXXXX.rs 9:1] ; connect different types: ; lhs: UInt<2> ; rhs: UInt<1> connect __connect_variant_body_4, bits(i1.body, 0, 0) @[module-XXXXXXXXXX.rs 9:1] wire _bundle_literal_expr_5: Ty1 connect _bundle_literal_expr_5.tag, UInt<2>(0h0) connect _bundle_literal_expr_5.body, pad(__connect_variant_body_4, 3) connect o2, _bundle_literal_expr_5 @[module-XXXXXXXXXX.rs 9:1] else when eq(i1.tag, UInt<2>(0h1)): @[module-XXXXXXXXXX.rs 9:1] wire __connect_variant_body_5: Ty3 @[module-XXXXXXXXXX.rs 9:1] wire _cast_bits_to_bundle_expr_3: Ty2 wire _cast_bits_to_bundle_expr_flattened_3: Ty2 connect _cast_bits_to_bundle_expr_flattened_3.tag, bits(bits(i1.body, 1, 0), 0, 0) connect _cast_bits_to_bundle_expr_3.tag, _cast_bits_to_bundle_expr_flattened_3.tag connect _cast_bits_to_bundle_expr_flattened_3.body, bits(bits(i1.body, 1, 0), 1, 1) connect _cast_bits_to_bundle_expr_3.body, _cast_bits_to_bundle_expr_flattened_3.body when eq(_cast_bits_to_bundle_expr_3.tag, UInt<1>(0h0)): @[module-XXXXXXXXXX.rs 9:1] wire _bundle_literal_expr_6: Ty3 connect _bundle_literal_expr_6.tag, UInt<1>(0h0) connect _bundle_literal_expr_6.body, UInt<2>(0h0) connect __connect_variant_body_5, _bundle_literal_expr_6 @[module-XXXXXXXXXX.rs 9:1] else: wire __connect_variant_body_6: SInt<2> @[module-XXXXXXXXXX.rs 9:1] wire _cast_bits_to_bundle_expr_4: Ty2 wire _cast_bits_to_bundle_expr_flattened_4: Ty2 connect _cast_bits_to_bundle_expr_flattened_4.tag, bits(bits(i1.body, 1, 0), 0, 0) connect _cast_bits_to_bundle_expr_4.tag, _cast_bits_to_bundle_expr_flattened_4.tag connect _cast_bits_to_bundle_expr_flattened_4.body, bits(bits(i1.body, 1, 0), 1, 1) connect _cast_bits_to_bundle_expr_4.body, _cast_bits_to_bundle_expr_flattened_4.body ; connect different types: ; lhs: SInt<2> ; rhs: SInt<1> connect __connect_variant_body_6, asSInt(bits(_cast_bits_to_bundle_expr_4.body, 0, 0)) @[module-XXXXXXXXXX.rs 9:1] wire _bundle_literal_expr_7: Ty3 connect _bundle_literal_expr_7.tag, UInt<1>(0h1) connect _bundle_literal_expr_7.body, asUInt(__connect_variant_body_6) connect __connect_variant_body_5, _bundle_literal_expr_7 @[module-XXXXXXXXXX.rs 9:1] wire _bundle_literal_expr_8: Ty1 connect _bundle_literal_expr_8.tag, UInt<2>(0h1) wire _cast_bundle_to_bits_expr_2: Ty3 connect _cast_bundle_to_bits_expr_2.tag, __connect_variant_body_5.tag connect _cast_bundle_to_bits_expr_2.body, __connect_variant_body_5.body wire _cast_to_bits_expr_2: UInt<3> connect _cast_to_bits_expr_2, cat(_cast_bundle_to_bits_expr_2.body, _cast_bundle_to_bits_expr_2.tag) connect _bundle_literal_expr_8.body, _cast_to_bits_expr_2 connect o2, _bundle_literal_expr_8 @[module-XXXXXXXXXX.rs 9:1] else: wire __connect_variant_body_7: Ty4 @[module-XXXXXXXXXX.rs 9:1] wire _cast_bits_to_bundle_expr_5: Ty4 wire _cast_bits_to_bundle_expr_flattened_5: Ty4 connect _cast_bits_to_bundle_expr_flattened_5.tag, bits(bits(i1.body, 0, 0), 0, 0) connect _cast_bits_to_bundle_expr_5.tag, _cast_bits_to_bundle_expr_flattened_5.tag connect _cast_bits_to_bundle_expr_flattened_5.body, UInt<0>(0) connect _cast_bits_to_bundle_expr_5.body, _cast_bits_to_bundle_expr_flattened_5.body connect __connect_variant_body_7, _cast_bits_to_bundle_expr_5 @[module-XXXXXXXXXX.rs 9:1] wire _bundle_literal_expr_9: Ty1 connect _bundle_literal_expr_9.tag, UInt<2>(0h2) wire _cast_bundle_to_bits_expr_3: Ty4 connect _cast_bundle_to_bits_expr_3.tag, __connect_variant_body_7.tag connect _cast_bundle_to_bits_expr_3.body, __connect_variant_body_7.body wire _cast_to_bits_expr_3: UInt<1> connect _cast_to_bits_expr_3, cat(_cast_bundle_to_bits_expr_3.body, _cast_bundle_to_bits_expr_3.tag) connect _bundle_literal_expr_9.body, pad(_cast_to_bits_expr_3, 3) connect o2, _bundle_literal_expr_9 @[module-XXXXXXXXXX.rs 9:1] else: connect o1, i1 @[module-XXXXXXXXXX.rs 10:1] connect o2, i2 @[module-XXXXXXXXXX.rs 11:1] ", }; #[rustfmt::skip] // work around https://github.com/rust-lang/rustfmt/issues/6161 assert_export_firrtl! { m => options: ExportOptions { simplify_enums: Some(SimplifyEnumsKind::ReplaceWithUInt), ..ExportOptions::default() }, "/test/check_enum_connect_any.fir": r"FIRRTL version 3.2.0 circuit check_enum_connect_any: type Ty0 = {tag: UInt<2>, body: UInt<2>} type Ty1 = {tag: UInt<1>, body: UInt<1>} type Ty2 = {tag: UInt<2>, body: UInt<3>} type Ty3 = {tag: UInt<1>, body: UInt<2>} module check_enum_connect_any: @[module-XXXXXXXXXX.rs 1:1] input swap: UInt<1> @[module-XXXXXXXXXX.rs 2:1] input i1: UInt<4> @[module-XXXXXXXXXX.rs 3:1] input i2: UInt<5> @[module-XXXXXXXXXX.rs 4:1] output o1: UInt<4> @[module-XXXXXXXXXX.rs 5:1] output o2: UInt<5> @[module-XXXXXXXXXX.rs 6:1] when swap: @[module-XXXXXXXXXX.rs 7:1] when eq(bits(i2, 1, 0), UInt<2>(0h0)): @[module-XXXXXXXXXX.rs 8:1] wire __connect_variant_body: UInt<1> @[module-XXXXXXXXXX.rs 8:1] ; connect different types: ; lhs: UInt<1> ; rhs: UInt<2> connect __connect_variant_body, bits(bits(i2, 4, 2), 1, 0) @[module-XXXXXXXXXX.rs 8:1] wire _bundle_literal_expr: Ty0 connect _bundle_literal_expr.tag, UInt<2>(0h0) connect _bundle_literal_expr.body, pad(__connect_variant_body, 2) wire _cast_bundle_to_bits_expr: Ty0 connect _cast_bundle_to_bits_expr.tag, _bundle_literal_expr.tag connect _cast_bundle_to_bits_expr.body, _bundle_literal_expr.body wire _cast_to_bits_expr: UInt<4> connect _cast_to_bits_expr, cat(_cast_bundle_to_bits_expr.body, _cast_bundle_to_bits_expr.tag) connect o1, _cast_to_bits_expr @[module-XXXXXXXXXX.rs 8:1] else when eq(bits(i2, 1, 0), UInt<2>(0h1)): @[module-XXXXXXXXXX.rs 8:1] wire __connect_variant_body_1: UInt<2> @[module-XXXXXXXXXX.rs 8:1] when eq(bits(bits(bits(i2, 4, 2), 2, 0), 0, 0), UInt<1>(0h0)): @[module-XXXXXXXXXX.rs 8:1] wire _bundle_literal_expr_1: Ty1 connect _bundle_literal_expr_1.tag, UInt<1>(0h0) connect _bundle_literal_expr_1.body, UInt<1>(0h0) wire _cast_bundle_to_bits_expr_1: Ty1 connect _cast_bundle_to_bits_expr_1.tag, _bundle_literal_expr_1.tag connect _cast_bundle_to_bits_expr_1.body, _bundle_literal_expr_1.body wire _cast_to_bits_expr_1: UInt<2> connect _cast_to_bits_expr_1, cat(_cast_bundle_to_bits_expr_1.body, _cast_bundle_to_bits_expr_1.tag) connect __connect_variant_body_1, _cast_to_bits_expr_1 @[module-XXXXXXXXXX.rs 8:1] else: wire __connect_variant_body_2: SInt<1> @[module-XXXXXXXXXX.rs 8:1] ; connect different types: ; lhs: SInt<1> ; rhs: SInt<2> connect __connect_variant_body_2, asSInt(bits(bits(bits(bits(i2, 4, 2), 2, 0), 2, 1), 1, 0)) @[module-XXXXXXXXXX.rs 8:1] wire _bundle_literal_expr_2: Ty1 connect _bundle_literal_expr_2.tag, UInt<1>(0h1) connect _bundle_literal_expr_2.body, asUInt(__connect_variant_body_2) wire _cast_bundle_to_bits_expr_2: Ty1 connect _cast_bundle_to_bits_expr_2.tag, _bundle_literal_expr_2.tag connect _cast_bundle_to_bits_expr_2.body, _bundle_literal_expr_2.body wire _cast_to_bits_expr_2: UInt<2> connect _cast_to_bits_expr_2, cat(_cast_bundle_to_bits_expr_2.body, _cast_bundle_to_bits_expr_2.tag) connect __connect_variant_body_1, _cast_to_bits_expr_2 @[module-XXXXXXXXXX.rs 8:1] wire _bundle_literal_expr_3: Ty0 connect _bundle_literal_expr_3.tag, UInt<2>(0h1) connect _bundle_literal_expr_3.body, __connect_variant_body_1 wire _cast_bundle_to_bits_expr_3: Ty0 connect _cast_bundle_to_bits_expr_3.tag, _bundle_literal_expr_3.tag connect _cast_bundle_to_bits_expr_3.body, _bundle_literal_expr_3.body wire _cast_to_bits_expr_3: UInt<4> connect _cast_to_bits_expr_3, cat(_cast_bundle_to_bits_expr_3.body, _cast_bundle_to_bits_expr_3.tag) connect o1, _cast_to_bits_expr_3 @[module-XXXXXXXXXX.rs 8:1] else: wire __connect_variant_body_3: UInt<1> @[module-XXXXXXXXXX.rs 8:1] connect __connect_variant_body_3, bits(bits(i2, 4, 2), 0, 0) @[module-XXXXXXXXXX.rs 8:1] wire _bundle_literal_expr_4: Ty0 connect _bundle_literal_expr_4.tag, UInt<2>(0h2) connect _bundle_literal_expr_4.body, pad(__connect_variant_body_3, 2) wire _cast_bundle_to_bits_expr_4: Ty0 connect _cast_bundle_to_bits_expr_4.tag, _bundle_literal_expr_4.tag connect _cast_bundle_to_bits_expr_4.body, _bundle_literal_expr_4.body wire _cast_to_bits_expr_4: UInt<4> connect _cast_to_bits_expr_4, cat(_cast_bundle_to_bits_expr_4.body, _cast_bundle_to_bits_expr_4.tag) connect o1, _cast_to_bits_expr_4 @[module-XXXXXXXXXX.rs 8:1] when eq(bits(i1, 1, 0), UInt<2>(0h0)): @[module-XXXXXXXXXX.rs 9:1] wire __connect_variant_body_4: UInt<2> @[module-XXXXXXXXXX.rs 9:1] ; connect different types: ; lhs: UInt<2> ; rhs: UInt<1> connect __connect_variant_body_4, bits(bits(i1, 3, 2), 0, 0) @[module-XXXXXXXXXX.rs 9:1] wire _bundle_literal_expr_5: Ty2 connect _bundle_literal_expr_5.tag, UInt<2>(0h0) connect _bundle_literal_expr_5.body, pad(__connect_variant_body_4, 3) wire _cast_bundle_to_bits_expr_5: Ty2 connect _cast_bundle_to_bits_expr_5.tag, _bundle_literal_expr_5.tag connect _cast_bundle_to_bits_expr_5.body, _bundle_literal_expr_5.body wire _cast_to_bits_expr_5: UInt<5> connect _cast_to_bits_expr_5, cat(_cast_bundle_to_bits_expr_5.body, _cast_bundle_to_bits_expr_5.tag) connect o2, _cast_to_bits_expr_5 @[module-XXXXXXXXXX.rs 9:1] else when eq(bits(i1, 1, 0), UInt<2>(0h1)): @[module-XXXXXXXXXX.rs 9:1] wire __connect_variant_body_5: UInt<3> @[module-XXXXXXXXXX.rs 9:1] when eq(bits(bits(bits(i1, 3, 2), 1, 0), 0, 0), UInt<1>(0h0)): @[module-XXXXXXXXXX.rs 9:1] wire _bundle_literal_expr_6: Ty3 connect _bundle_literal_expr_6.tag, UInt<1>(0h0) connect _bundle_literal_expr_6.body, UInt<2>(0h0) wire _cast_bundle_to_bits_expr_6: Ty3 connect _cast_bundle_to_bits_expr_6.tag, _bundle_literal_expr_6.tag connect _cast_bundle_to_bits_expr_6.body, _bundle_literal_expr_6.body wire _cast_to_bits_expr_6: UInt<3> connect _cast_to_bits_expr_6, cat(_cast_bundle_to_bits_expr_6.body, _cast_bundle_to_bits_expr_6.tag) connect __connect_variant_body_5, _cast_to_bits_expr_6 @[module-XXXXXXXXXX.rs 9:1] else: wire __connect_variant_body_6: SInt<2> @[module-XXXXXXXXXX.rs 9:1] ; connect different types: ; lhs: SInt<2> ; rhs: SInt<1> connect __connect_variant_body_6, asSInt(bits(bits(bits(bits(i1, 3, 2), 1, 0), 1, 1), 0, 0)) @[module-XXXXXXXXXX.rs 9:1] wire _bundle_literal_expr_7: Ty3 connect _bundle_literal_expr_7.tag, UInt<1>(0h1) connect _bundle_literal_expr_7.body, asUInt(__connect_variant_body_6) wire _cast_bundle_to_bits_expr_7: Ty3 connect _cast_bundle_to_bits_expr_7.tag, _bundle_literal_expr_7.tag connect _cast_bundle_to_bits_expr_7.body, _bundle_literal_expr_7.body wire _cast_to_bits_expr_7: UInt<3> connect _cast_to_bits_expr_7, cat(_cast_bundle_to_bits_expr_7.body, _cast_bundle_to_bits_expr_7.tag) connect __connect_variant_body_5, _cast_to_bits_expr_7 @[module-XXXXXXXXXX.rs 9:1] wire _bundle_literal_expr_8: Ty2 connect _bundle_literal_expr_8.tag, UInt<2>(0h1) connect _bundle_literal_expr_8.body, __connect_variant_body_5 wire _cast_bundle_to_bits_expr_8: Ty2 connect _cast_bundle_to_bits_expr_8.tag, _bundle_literal_expr_8.tag connect _cast_bundle_to_bits_expr_8.body, _bundle_literal_expr_8.body wire _cast_to_bits_expr_8: UInt<5> connect _cast_to_bits_expr_8, cat(_cast_bundle_to_bits_expr_8.body, _cast_bundle_to_bits_expr_8.tag) connect o2, _cast_to_bits_expr_8 @[module-XXXXXXXXXX.rs 9:1] else: wire __connect_variant_body_7: UInt<1> @[module-XXXXXXXXXX.rs 9:1] connect __connect_variant_body_7, bits(bits(i1, 3, 2), 0, 0) @[module-XXXXXXXXXX.rs 9:1] wire _bundle_literal_expr_9: Ty2 connect _bundle_literal_expr_9.tag, UInt<2>(0h2) connect _bundle_literal_expr_9.body, pad(__connect_variant_body_7, 3) wire _cast_bundle_to_bits_expr_9: Ty2 connect _cast_bundle_to_bits_expr_9.tag, _bundle_literal_expr_9.tag connect _cast_bundle_to_bits_expr_9.body, _bundle_literal_expr_9.body wire _cast_to_bits_expr_9: UInt<5> connect _cast_to_bits_expr_9, cat(_cast_bundle_to_bits_expr_9.body, _cast_bundle_to_bits_expr_9.tag) connect o2, _cast_to_bits_expr_9 @[module-XXXXXXXXXX.rs 9:1] else: connect o1, i1 @[module-XXXXXXXXXX.rs 10:1] connect o2, i2 @[module-XXXXXXXXXX.rs 11:1] ", }; }