fayalite/crates/fayalite/tests/module.rs

4029 lines
162 KiB
Rust

// 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<Bool, 3>),
}
#[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<UInt<8>, 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: UInt<8> = reg_builder().clock_domain(clock_domain).reset(8_hdl_u8);
connect(m2.i, i);
connect(r, m2.o);
connect(
o,
#[hdl]
[r, r, 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: 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, m2.o @[module-XXXXXXXXXX.rs 16:1]
wire _array_literal_expr: UInt<8>[3]
connect _array_literal_expr[0], r
connect _array_literal_expr[1], r
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<const N: usize>()
where
ConstUsize<N>: KnownSize,
{
#[hdl]
let i: UInt<8> = m.input();
#[hdl]
let o: Array<UInt<8>, 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_1.fir": r"FIRRTL version 3.2.0
circuit check_array_repeat_1:
module check_array_repeat_1: @[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<T, #[hdl(skip)] U, const N: usize, #[hdl(skip)] const M: usize>(v: U)
where
T: StaticType,
ConstUsize<N>: KnownSize,
U: std::fmt::Display,
{
dbg!(M);
#[hdl]
let i: T = m.input();
#[hdl]
let o: Array<T, N> = m.output();
let bytes = v.to_string().as_bytes().to_expr();
#[hdl]
let o2: Array<UInt<8>> = 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::<UInt<8>, _, 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<UInt<8>, 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<T> {
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<UInt<16>> = 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<UInt<8>> = 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<UInt<8>> = m.input();
#[hdl]
let i2: TestEnum = m.input();
#[hdl]
let o: Array<UInt<8>, 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<UInt<8>, 3> = m.output();
#[hdl]
let waddr: UInt<4> = m.input();
#[hdl]
let wdata: Array<UInt<8>, 3> = m.input();
#[hdl]
let wmask: Array<Bool, 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(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<Array<UInt<8>, 2>, 3> = m.output();
#[hdl]
let waddr: UInt<4> = m.input();
#[hdl]
let wdata: Array<Array<UInt<8>, 2>, 3> = m.input();
#[hdl]
let wmask: Array<Array<Bool, 2>, 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_1.mem",
"hexOrBinary": "h",
"target": "~check_memory_of_arrays|check_memory_of_arrays>mem_1"
}
]]
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_1: @[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_1.r0.data[0] @[module-XXXXXXXXXX.rs 9:1]
connect mem_r0.data[0][1], mem_1.r0.data[1] @[module-XXXXXXXXXX.rs 9:1]
connect mem_r0.data[1][0], mem_1.r0.data[2] @[module-XXXXXXXXXX.rs 9:1]
connect mem_r0.data[1][1], mem_1.r0.data[3] @[module-XXXXXXXXXX.rs 9:1]
connect mem_r0.data[2][0], mem_1.r0.data[4] @[module-XXXXXXXXXX.rs 9:1]
connect mem_r0.data[2][1], mem_1.r0.data[5] @[module-XXXXXXXXXX.rs 9:1]
connect mem_1.w1.data[0], mem_w1.data[0][0] @[module-XXXXXXXXXX.rs 14:1]
connect mem_1.w1.mask[0], mem_w1.mask[0][0] @[module-XXXXXXXXXX.rs 14:1]
connect mem_1.w1.data[1], mem_w1.data[0][1] @[module-XXXXXXXXXX.rs 14:1]
connect mem_1.w1.mask[1], mem_w1.mask[0][1] @[module-XXXXXXXXXX.rs 14:1]
connect mem_1.w1.data[2], mem_w1.data[1][0] @[module-XXXXXXXXXX.rs 14:1]
connect mem_1.w1.mask[2], mem_w1.mask[1][0] @[module-XXXXXXXXXX.rs 14:1]
connect mem_1.w1.data[3], mem_w1.data[1][1] @[module-XXXXXXXXXX.rs 14:1]
connect mem_1.w1.mask[3], mem_w1.mask[1][1] @[module-XXXXXXXXXX.rs 14:1]
connect mem_1.w1.data[4], mem_w1.data[2][0] @[module-XXXXXXXXXX.rs 14:1]
connect mem_1.w1.mask[4], mem_w1.mask[2][0] @[module-XXXXXXXXXX.rs 14:1]
connect mem_1.w1.data[5], mem_w1.data[2][1] @[module-XXXXXXXXXX.rs 14:1]
connect mem_1.w1.mask[5], mem_w1.mask[2][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_arrays/mem_1.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<Array<UInt<8>, 2>, 3>, UInt<2>) = m.output();
#[hdl]
let waddr: UInt<4> = m.input();
#[hdl]
let wdata: (Array<Array<UInt<8>, 2>, 3>, UInt<2>) = m.input();
#[hdl]
let wmask: (Array<Array<Bool, 2>, 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_1.mem",
"hexOrBinary": "b",
"target": "~check_memory_of_enum|check_memory_of_enum>mem_1"
}
]]
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_1: @[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_1.r0.data, 8)
when eq(UInt<2>(0), tail(mem_1.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_1.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_1.w1.data, _cast_enum_to_bits_expr @[module-XXXXXXXXXX.rs 14:1]
connect mem_1.w1.mask, mem_w1.mask @[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 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_1.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_1: 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_1.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_1.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_1.addr @[module-XXXXXXXXXX.rs 14:1]
connect mem_tag.w1.clk, mem_w1_1.clk @[module-XXXXXXXXXX.rs 14:1]
connect mem_tag.w1.en, mem_w1_1.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_1.data.body @[module-XXXXXXXXXX.rs 14:1]
connect mem_body.w1.mask, mem_w1_1.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_1.addr @[module-XXXXXXXXXX.rs 14:1]
connect mem_body.w1.clk, mem_w1_1.clk @[module-XXXXXXXXXX.rs 14:1]
connect mem_body.w1.en, mem_w1_1.en @[module-XXXXXXXXXX.rs 14:1]
wire mem_w1: Ty9 @[module-XXXXXXXXXX.rs 14:1]
connect mem_w1_1.addr, mem_w1.addr @[module-XXXXXXXXXX.rs 14:1]
connect mem_w1_1.en, mem_w1.en @[module-XXXXXXXXXX.rs 14:1]
connect mem_w1_1.clk, mem_w1.clk @[module-XXXXXXXXXX.rs 14:1]
connect mem_w1_1.data, mem_w1.data @[module-XXXXXXXXXX.rs 14:1]
connect mem_w1_1.mask.tag, mem_w1.mask @[module-XXXXXXXXXX.rs 14:1]
connect mem_w1_1.mask.body, mem_w1.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.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_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_1: 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_1.data.tag @[module-XXXXXXXXXX.rs 14:1]
connect mem_tag.w1.mask, mem_w1_1.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_1.addr @[module-XXXXXXXXXX.rs 14:1]
connect mem_tag.w1.clk, mem_w1_1.clk @[module-XXXXXXXXXX.rs 14:1]
connect mem_tag.w1.en, mem_w1_1.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_1.data.body @[module-XXXXXXXXXX.rs 14:1]
connect mem_body.w1.mask, mem_w1_1.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_1.addr @[module-XXXXXXXXXX.rs 14:1]
connect mem_body.w1.clk, mem_w1_1.clk @[module-XXXXXXXXXX.rs 14:1]
connect mem_body.w1.en, mem_w1_1.en @[module-XXXXXXXXXX.rs 14:1]
wire mem_w1: Ty8 @[module-XXXXXXXXXX.rs 14:1]
connect mem_w1_1.addr, mem_w1.addr @[module-XXXXXXXXXX.rs 14:1]
connect mem_w1_1.en, mem_w1.en @[module-XXXXXXXXXX.rs 14:1]
connect mem_w1_1.clk, mem_w1.clk @[module-XXXXXXXXXX.rs 14:1]
connect mem_w1_1.data, mem_w1.data @[module-XXXXXXXXXX.rs 14:1]
connect mem_w1_1.mask.tag, mem_w1.mask @[module-XXXXXXXXXX.rs 14:1]
connect mem_w1_1.mask.body, mem_w1.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.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_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<TestEnum, 2> = m.output();
#[hdl]
let waddr: UInt<8> = m.input();
#[hdl]
let wdata: Array<TestEnum, 2> = m.input();
#[hdl]
let wmask: Array<Bool, 2> = 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_1: @[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_1.r0.data[0], 8)
when eq(UInt<2>(0), tail(mem_1.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_1.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_1.r0.data[1], 8)
when eq(UInt<2>(0), tail(mem_1.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_1.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_1.w1.data[0], _cast_enum_to_bits_expr @[module-XXXXXXXXXX.rs 14:1]
connect mem_1.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_1.w1.data[1], _cast_enum_to_bits_expr_1 @[module-XXXXXXXXXX.rs 14:1]
connect mem_1.w1.mask[1], 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]
",
};
}
#[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<UInt<4>, 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<UInt<4>, 2> = m.input();
#[hdl]
let wmask: Array<Bool, 2> = 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<T: Type>(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_1.fir": r"FIRRTL version 3.2.0
circuit check_uninit_1:
type Ty0 = {}
type Ty1 = {|HdlNone, HdlSome: Ty0|}
module check_uninit_1: @[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, B, C> {
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<UInt<1>, HdlOption<SInt<1>>, HdlOption<()>> = m.input();
#[hdl]
let i2: OneOfThree<UInt<2>, HdlOption<SInt<2>>, HdlOption<()>> = m.input();
#[hdl]
let o1: OneOfThree<UInt<1>, HdlOption<SInt<1>>, HdlOption<()>> = m.output();
#[hdl]
let o2: OneOfThree<UInt<2>, HdlOption<SInt<2>>, 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]
",
};
}