forked from libre-chip/fayalite
4029 lines
162 KiB
Rust
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]
|
|
",
|
|
};
|
|
}
|