forked from libre-chip/fayalite
add more memory tests
This commit is contained in:
parent
c756aeec70
commit
2af38de900
3 changed files with 5960 additions and 5 deletions
|
|
@ -271,7 +271,7 @@ fn test_shift_register() {
|
|||
assert_eq!(
|
||||
*expected,
|
||||
sim.read_bool(sim.io().q),
|
||||
"cycle: {cycle}\nvcd:\n{}",
|
||||
"vcd:\n{}\ncycle: {cycle}",
|
||||
String::from_utf8(writer.take()).unwrap(),
|
||||
);
|
||||
}
|
||||
|
|
@ -473,7 +473,7 @@ fn test_enums() {
|
|||
assert_eq!(
|
||||
expected,
|
||||
io,
|
||||
"cycle: {cycle}\nvcd:\n{}",
|
||||
"vcd:\n{}\ncycle: {cycle}",
|
||||
String::from_utf8(writer.take()).unwrap(),
|
||||
);
|
||||
sim.write_clock(sim.io().cd.clk, false);
|
||||
|
|
@ -671,7 +671,7 @@ fn test_memories() {
|
|||
assert_eq!(
|
||||
expected,
|
||||
io,
|
||||
"cycle: {cycle}\nvcd:\n{}",
|
||||
"vcd:\n{}\ncycle: {cycle}",
|
||||
String::from_utf8(writer.take()).unwrap(),
|
||||
);
|
||||
sim.advance_time(SimDuration::from_micros(1));
|
||||
|
|
@ -947,7 +947,7 @@ fn test_memories2() {
|
|||
assert_eq!(
|
||||
expected,
|
||||
io,
|
||||
"cycle: {cycle}\nvcd:\n{}",
|
||||
"vcd:\n{}\ncycle: {cycle}",
|
||||
String::from_utf8(writer.take()).unwrap(),
|
||||
);
|
||||
sim.advance_time(SimDuration::from_nanos(250));
|
||||
|
|
@ -967,4 +967,241 @@ fn test_memories2() {
|
|||
}
|
||||
}
|
||||
|
||||
// TODO: add more tests for memories
|
||||
#[hdl_module(outline_generated)]
|
||||
pub fn memories3() {
|
||||
#[hdl]
|
||||
let r: fayalite::memory::ReadStruct<Array<UInt<8>, 8>, ConstUsize<3>> = m.input();
|
||||
#[hdl]
|
||||
let w: fayalite::memory::WriteStruct<Array<UInt<8>, 8>, ConstUsize<3>> = m.input();
|
||||
#[hdl]
|
||||
let mut mem: MemBuilder<Array<UInt<8>, 8>> = memory();
|
||||
mem.depth(8);
|
||||
mem.read_latency(2);
|
||||
mem.write_latency(NonZeroUsize::new(2).unwrap());
|
||||
mem.read_under_write(ReadUnderWrite::Old);
|
||||
connect_any(mem.new_read_port(), r);
|
||||
connect_any(mem.new_write_port(), w);
|
||||
}
|
||||
|
||||
#[hdl]
|
||||
#[test]
|
||||
fn test_memories3() {
|
||||
let _n = SourceLocation::normalize_files_for_tests();
|
||||
let mut sim = Simulation::new(memories3());
|
||||
let mut writer = RcWriter::default();
|
||||
sim.add_trace_writer(VcdWriterDecls::new(writer.clone()));
|
||||
sim.write_clock(sim.io().r.clk, false);
|
||||
sim.write_clock(sim.io().w.clk, false);
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
|
||||
struct IO {
|
||||
r_addr: u8,
|
||||
r_en: bool,
|
||||
r_data: [u8; 8],
|
||||
w_addr: u8,
|
||||
w_en: bool,
|
||||
w_data: [u8; 8],
|
||||
w_mask: [bool; 8],
|
||||
}
|
||||
let io_cycles = [
|
||||
IO {
|
||||
r_addr: 0,
|
||||
r_en: false,
|
||||
r_data: [0; 8],
|
||||
w_addr: 0,
|
||||
w_en: true,
|
||||
w_data: [0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0],
|
||||
w_mask: [false, true, false, true, true, false, false, true],
|
||||
},
|
||||
IO {
|
||||
r_addr: 0,
|
||||
r_en: true,
|
||||
r_data: [0; 8],
|
||||
w_addr: 1,
|
||||
w_en: false,
|
||||
w_data: [0; 8],
|
||||
w_mask: [false; 8],
|
||||
},
|
||||
IO {
|
||||
r_addr: 0,
|
||||
r_en: true,
|
||||
r_data: [0, 0x34, 0, 0x78, 0x9A, 0, 0, 0xF0],
|
||||
w_addr: 1,
|
||||
w_en: false,
|
||||
w_data: [0; 8],
|
||||
w_mask: [false; 8],
|
||||
},
|
||||
IO {
|
||||
r_addr: 0,
|
||||
r_en: true,
|
||||
r_data: [0, 0x34, 0, 0x78, 0x9A, 0, 0, 0xF0],
|
||||
w_addr: 0,
|
||||
w_en: true,
|
||||
w_data: [0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10],
|
||||
w_mask: [true; 8],
|
||||
},
|
||||
IO {
|
||||
r_addr: 0,
|
||||
r_en: true,
|
||||
r_data: [0, 0x34, 0, 0x78, 0x9A, 0, 0, 0xF0],
|
||||
w_addr: 0,
|
||||
w_en: true,
|
||||
w_data: [0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10],
|
||||
w_mask: [true; 8],
|
||||
},
|
||||
IO {
|
||||
r_addr: 0,
|
||||
r_en: true,
|
||||
r_data: [0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10],
|
||||
w_addr: 0,
|
||||
w_en: true,
|
||||
w_data: [0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10],
|
||||
w_mask: [true; 8],
|
||||
},
|
||||
IO {
|
||||
r_addr: 0,
|
||||
r_en: false,
|
||||
r_data: [0; 8],
|
||||
w_addr: 1,
|
||||
w_en: true,
|
||||
w_data: [0x13, 0x57, 0x9B, 0xDF, 0x02, 0x46, 0x8A, 0xCE],
|
||||
w_mask: [true; 8],
|
||||
},
|
||||
IO {
|
||||
r_addr: 0,
|
||||
r_en: false,
|
||||
r_data: [0; 8],
|
||||
w_addr: 2,
|
||||
w_en: true,
|
||||
w_data: *b"testing!",
|
||||
w_mask: [true; 8],
|
||||
},
|
||||
IO {
|
||||
r_addr: 0,
|
||||
r_en: false,
|
||||
r_data: [0; 8],
|
||||
w_addr: 3,
|
||||
w_en: true,
|
||||
w_data: *b"more tst",
|
||||
w_mask: [true; 8],
|
||||
},
|
||||
IO {
|
||||
r_addr: 0,
|
||||
r_en: true,
|
||||
r_data: [0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10],
|
||||
w_addr: 0,
|
||||
w_en: false,
|
||||
w_data: [0; 8],
|
||||
w_mask: [false; 8],
|
||||
},
|
||||
IO {
|
||||
r_addr: 1,
|
||||
r_en: true,
|
||||
r_data: [0x13, 0x57, 0x9B, 0xDF, 0x02, 0x46, 0x8A, 0xCE],
|
||||
w_addr: 0,
|
||||
w_en: false,
|
||||
w_data: [0; 8],
|
||||
w_mask: [false; 8],
|
||||
},
|
||||
IO {
|
||||
r_addr: 2,
|
||||
r_en: true,
|
||||
r_data: *b"testing!",
|
||||
w_addr: 0,
|
||||
w_en: false,
|
||||
w_data: [0; 8],
|
||||
w_mask: [false; 8],
|
||||
},
|
||||
IO {
|
||||
r_addr: 3,
|
||||
r_en: true,
|
||||
r_data: *b"more tst",
|
||||
w_addr: 0,
|
||||
w_en: false,
|
||||
w_data: [0; 8],
|
||||
w_mask: [false; 8],
|
||||
},
|
||||
];
|
||||
for cycle in 0..io_cycles.len() + 2 {
|
||||
{
|
||||
let IO {
|
||||
r_addr,
|
||||
r_en,
|
||||
r_data: _,
|
||||
w_addr,
|
||||
w_en,
|
||||
w_data,
|
||||
w_mask,
|
||||
} = io_cycles.get(cycle).copied().unwrap_or(IO {
|
||||
r_addr: 0,
|
||||
r_en: false,
|
||||
r_data: [0; 8],
|
||||
w_addr: 0,
|
||||
w_en: false,
|
||||
w_data: [0; 8],
|
||||
w_mask: [false; 8],
|
||||
});
|
||||
sim.write_bool_or_int(sim.io().r.addr, r_addr.cast_to_static());
|
||||
sim.write_bool(sim.io().r.en, r_en);
|
||||
sim.write_bool_or_int(sim.io().w.addr, w_addr.cast_to_static());
|
||||
sim.write_bool(sim.io().w.en, w_en);
|
||||
for (i, v) in w_data.into_iter().enumerate() {
|
||||
sim.write_bool_or_int(sim.io().w.data[i], v);
|
||||
}
|
||||
for (i, v) in w_mask.into_iter().enumerate() {
|
||||
sim.write_bool_or_int(sim.io().w.mask[i], v);
|
||||
}
|
||||
}
|
||||
sim.advance_time(SimDuration::from_nanos(250));
|
||||
sim.write_clock(sim.io().r.clk, true);
|
||||
sim.write_clock(sim.io().w.clk, true);
|
||||
sim.advance_time(SimDuration::from_nanos(250));
|
||||
if let Some(
|
||||
expected @ IO {
|
||||
r_addr,
|
||||
r_en,
|
||||
r_data: _,
|
||||
w_addr,
|
||||
w_en,
|
||||
w_data,
|
||||
w_mask,
|
||||
},
|
||||
) = cycle.checked_sub(1).and_then(|i| io_cycles.get(i).copied())
|
||||
{
|
||||
let io = IO {
|
||||
r_addr,
|
||||
r_en,
|
||||
r_data: std::array::from_fn(|i| {
|
||||
sim.read_bool_or_int(sim.io().r.data[i])
|
||||
.to_bigint()
|
||||
.try_into()
|
||||
.expect("known to be in range")
|
||||
}),
|
||||
w_addr,
|
||||
w_en,
|
||||
w_data,
|
||||
w_mask,
|
||||
};
|
||||
assert_eq!(
|
||||
expected,
|
||||
io,
|
||||
"vcd:\n{}\ncycle: {cycle}",
|
||||
String::from_utf8(writer.take()).unwrap(),
|
||||
);
|
||||
}
|
||||
sim.advance_time(SimDuration::from_nanos(250));
|
||||
sim.write_clock(sim.io().r.clk, false);
|
||||
sim.write_clock(sim.io().w.clk, false);
|
||||
sim.advance_time(SimDuration::from_nanos(250));
|
||||
}
|
||||
sim.flush_traces().unwrap();
|
||||
let vcd = String::from_utf8(writer.take()).unwrap();
|
||||
println!("####### VCD:\n{vcd}\n#######");
|
||||
if vcd != include_str!("sim/expected/memories3.vcd") {
|
||||
panic!();
|
||||
}
|
||||
let sim_debug = format!("{sim:#?}");
|
||||
println!("#######\n{sim_debug}\n#######");
|
||||
if sim_debug != include_str!("sim/expected/memories3.txt") {
|
||||
panic!();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue