tests/sim: add WIP test for enums
This commit is contained in:
parent
e4cf66adf8
commit
ca759168ff
|
@ -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
|
||||
|
|
0
crates/fayalite/tests/sim/expected/enums.txt
Normal file
0
crates/fayalite/tests/sim/expected/enums.txt
Normal file
0
crates/fayalite/tests/sim/expected/enums.vcd
Normal file
0
crates/fayalite/tests/sim/expected/enums.vcd
Normal file
Loading…
Reference in a new issue