tests/sim: add WIP test for enums

This commit is contained in:
Jacob Lifshay 2024-12-10 23:37:26 -08:00
parent e4cf66adf8
commit ca759168ff
Signed by: programmerjake
SSH key fingerprint: SHA256:HnFTLGpSm4Q4Fj502oCFisjZSoakwEuTsJJMSke63RQ
3 changed files with 200 additions and 1 deletions

View file

@ -293,5 +293,204 @@ fn test_shift_register() {
}
}
// TODO: add tests for enums
#[hdl_module(outline_generated)]
pub fn enums() {
#[hdl]
let cd: ClockDomain<SyncReset> = m.input();
#[hdl]
let en: Bool = m.input();
#[hdl]
let which_in: UInt<2> = m.input();
#[hdl]
let data_in: UInt<4> = m.input();
#[hdl]
let which_out: UInt<2> = m.output();
#[hdl]
let data_out: UInt<4> = m.output();
#[hdl]
struct MyStruct<T> {
a: T,
b: SInt<2>,
}
#[hdl]
enum MyEnum {
A,
B((UInt<1>, Bool)),
C(MyStruct<Array<UInt<1>, 2>>),
}
#[hdl]
let the_reg = reg_builder().clock_domain(cd).reset(MyEnum.A());
#[hdl]
if en {
#[hdl]
if which_in.cmp_eq(0_hdl_u2) {
connect(the_reg, MyEnum.A());
} else if which_in.cmp_eq(1_hdl_u2) {
connect(the_reg, MyEnum.B((data_in[0].cast_to_static(), data_in[1])));
} else {
connect(
the_reg,
MyEnum.C(
#[hdl]
MyStruct {
a: #[hdl]
[data_in[0].cast_to_static(), data_in[1].cast_to_static()],
b: data_in[2..4].cast_to_static(),
},
),
);
}
}
#[hdl]
match the_reg {
MyEnum::A => {
connect(which_out, 0_hdl_u2);
connect(data_out, 0_hdl_u4);
}
MyEnum::B(v) => {
connect(which_out, 1_hdl_u2);
connect_any(data_out, v.0 | (v.1.cast_to_static::<UInt<1>>() << 1));
}
MyEnum::C(v) => {
connect(which_out, 2_hdl_u2);
connect_any(data_out, v.cast_to_bits());
}
}
}
#[cfg(todo)] // FIXME: enum lowering currently broken
#[hdl]
#[test]
fn test_enums() {
let _n = SourceLocation::normalize_files_for_tests();
let mut sim = Simulation::new(enums());
let mut writer = RcWriter::default();
sim.add_trace_writer(VcdWriterDecls::new(writer.clone()));
sim.write_clock(sim.io().cd.clk, false);
sim.write_reset(sim.io().cd.rst, true);
sim.write_bool(sim.io().en, false);
sim.write_bool_or_int(sim.io().which_in, 0_hdl_u2);
sim.write_bool_or_int(sim.io().data_in, 0_hdl_u4);
sim.advance_time(SimDuration::from_micros(1));
sim.write_clock(sim.io().cd.clk, true);
sim.advance_time(SimDuration::from_nanos(100));
sim.write_reset(sim.io().cd.rst, false);
sim.advance_time(SimDuration::from_nanos(900));
#[derive(Debug, PartialEq, Eq)]
struct IO {
en: bool,
which_in: u8,
data_in: u8,
which_out: u8,
data_out: u8,
}
let io_cycles = [
IO {
en: false,
which_in: 0,
data_in: 0,
which_out: 0,
data_out: 0,
},
IO {
en: true,
which_in: 1,
data_in: 0,
which_out: 0,
data_out: 0,
},
IO {
en: false,
which_in: 0,
data_in: 0,
which_out: 1,
data_out: 0,
},
IO {
en: true,
which_in: 1,
data_in: 0xF,
which_out: 1,
data_out: 0,
},
IO {
en: true,
which_in: 1,
data_in: 0xF,
which_out: 1,
data_out: 0x3,
},
IO {
en: true,
which_in: 2,
data_in: 0xF,
which_out: 1,
data_out: 0x3,
},
IO {
en: true,
which_in: 2,
data_in: 0xF,
which_out: 2,
data_out: 0xF,
},
];
for (
cycle,
expected @ IO {
en,
which_in,
data_in,
which_out: _,
data_out: _,
},
) in io_cycles.into_iter().enumerate()
{
sim.write_bool(sim.io().en, en);
sim.write_bool_or_int(sim.io().which_in, which_in.cast_to_static());
sim.write_bool_or_int(sim.io().data_in, data_in.cast_to_static());
let io = IO {
en,
which_in,
data_in,
which_out: sim
.read_bool_or_int(sim.io().which_out)
.to_bigint()
.try_into()
.expect("known to be in range"),
data_out: sim
.read_bool_or_int(sim.io().data_out)
.to_bigint()
.try_into()
.expect("known to be in range"),
};
assert_eq!(
expected,
io,
"cycle: {cycle}\nvcd:\n{}",
String::from_utf8(writer.take()).unwrap(),
);
sim.write_clock(sim.io().cd.clk, false);
sim.advance_time(SimDuration::from_micros(1));
sim.write_clock(sim.io().cd.clk, true);
sim.advance_time(SimDuration::from_micros(1));
}
sim.flush_traces().unwrap();
let vcd = String::from_utf8(writer.take()).unwrap();
println!("####### VCD:\n{vcd}\n#######");
if vcd != include_str!("sim/expected/enums.vcd") {
panic!();
}
let sim_debug = format!("{sim:#?}");
println!("#######\n{sim_debug}\n#######");
if sim_debug != include_str!("sim/expected/enums.txt") {
panic!();
}
}
// TODO: add tests for memories