tests/sim: add test_array_rw

This commit is contained in:
Jacob Lifshay 2025-01-12 21:36:54 -08:00
parent e3a2ccd41c
commit 404a2ee043
Signed by: programmerjake
SSH key fingerprint: SHA256:HnFTLGpSm4Q4Fj502oCFisjZSoakwEuTsJJMSke63RQ
3 changed files with 3273 additions and 0 deletions

View file

@ -1276,3 +1276,134 @@ fn test_duplicate_names() {
panic!();
}
}
#[hdl_module(outline_generated)]
pub fn array_rw() {
#[hdl]
let array_in: Array<UInt<8>, 16> = m.input();
#[hdl]
let array_out: Array<UInt<8>, 16> = m.output();
#[hdl]
let read_index: UInt<8> = m.input();
#[hdl]
let read_data: UInt<8> = m.output();
#[hdl]
let write_index: UInt<8> = m.input();
#[hdl]
let write_data: UInt<8> = m.input();
#[hdl]
let write_en: Bool = m.input();
#[hdl]
let array_wire = wire();
connect(array_wire, array_in);
connect(array_out, array_wire);
#[hdl]
if write_en {
connect(array_wire[write_index], write_data);
}
connect(read_data, array_wire[read_index]);
}
#[test]
fn test_array_rw() {
let _n = SourceLocation::normalize_files_for_tests();
let mut sim = Simulation::new(array_rw());
let mut writer = RcWriter::default();
sim.add_trace_writer(VcdWriterDecls::new(writer.clone()));
#[derive(Debug, PartialEq)]
struct State {
array_in: [u8; 16],
array_out: [u8; 16],
read_index: u8,
read_data: u8,
write_index: u8,
write_data: u8,
write_en: bool,
}
let mut states = Vec::new();
let array_in = [
0xFFu8, 0x7F, 0x3F, 0x1F, 0x0F, 0x07, 0x03, 0x01, //
0x00u8, 0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC, 0xFE,
];
for i in 0..=16 {
states.push(State {
array_in,
array_out: array_in,
read_index: i,
read_data: array_in.get(i as usize).copied().unwrap_or(0),
write_index: 0,
write_data: 0,
write_en: false,
});
}
for i in 0..=16u8 {
let mut array_out = array_in;
let write_data = i.wrapping_mul(i);
if let Some(v) = array_out.get_mut(i as usize) {
*v = write_data;
}
states.push(State {
array_in,
array_out,
read_index: 0,
read_data: array_out[0],
write_index: i,
write_data,
write_en: true,
});
}
for (cycle, expected) in states.into_iter().enumerate() {
let State {
array_in,
array_out: _,
read_index,
read_data: _,
write_index,
write_data,
write_en,
} = expected;
sim.write(sim.io().array_in, array_in);
sim.write(sim.io().read_index, read_index);
sim.write(sim.io().write_index, write_index);
sim.write(sim.io().write_data, write_data);
sim.write(sim.io().write_en, write_en);
sim.advance_time(SimDuration::from_micros(1));
let array_out = std::array::from_fn(|index| {
sim.read_bool_or_int(sim.io().array_out[index])
.to_bigint()
.try_into()
.expect("known to be in range")
});
let read_data = sim
.read_bool_or_int(sim.io().read_data)
.to_bigint()
.try_into()
.expect("known to be in range");
let state = State {
array_in,
array_out,
read_index,
read_data,
write_index,
write_data,
write_en,
};
assert_eq!(
state,
expected,
"vcd:\n{}\ncycle: {cycle}",
String::from_utf8(writer.take()).unwrap(),
);
}
sim.flush_traces().unwrap();
let vcd = String::from_utf8(writer.take()).unwrap();
println!("####### VCD:\n{vcd}\n#######");
if vcd != include_str!("sim/expected/array_rw.vcd") {
panic!();
}
let sim_debug = format!("{sim:#?}");
println!("#######\n{sim_debug}\n#######");
if sim_debug != include_str!("sim/expected/array_rw.txt") {
panic!();
}
}