sim: add WIP memory test

This commit is contained in:
Jacob Lifshay 2024-12-11 23:28:15 -08:00
parent 8616ee4737
commit 393f78a14d
Signed by: programmerjake
SSH key fingerprint: SHA256:HnFTLGpSm4Q4Fj502oCFisjZSoakwEuTsJJMSke63RQ
11 changed files with 1155 additions and 304 deletions

View file

@ -1,5 +1,6 @@
// SPDX-License-Identifier: LGPL-3.0-or-later
// See Notices.txt for copyright information
use fayalite::{
int::UIntValue,
prelude::*,
@ -7,6 +8,7 @@ use fayalite::{
sim::{time::SimDuration, vcd::VcdWriterDecls, Simulation},
util::RcWriter,
};
use std::num::NonZeroUsize;
#[hdl_module(outline_generated)]
pub fn connect_const() {
@ -492,4 +494,113 @@ fn test_enums() {
}
}
// TODO: add tests for memories
#[hdl_module(outline_generated)]
pub fn memories() {
#[hdl]
let r: fayalite::memory::ReadStruct<(UInt<8>, SInt<8>), ConstUsize<4>> = m.input();
#[hdl]
let w: fayalite::memory::WriteStruct<(UInt<8>, SInt<8>), ConstUsize<4>> = m.input();
#[hdl]
let mut mem = memory_with_init([(0x01u8, 0x23i8); 16]);
mem.read_latency(0);
mem.write_latency(NonZeroUsize::new(1).unwrap());
mem.read_under_write(ReadUnderWrite::Old);
connect_any(mem.new_read_port(), r);
connect_any(mem.new_write_port(), w);
}
#[cfg(todo)] // TODO: finish
#[hdl]
#[test]
fn test_memories() {
let _n = SourceLocation::normalize_files_for_tests();
let mut sim = Simulation::new(memories());
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)]
struct IO {
r_addr: u8,
r_en: bool,
r_data: (u8, i8),
w_addr: u8,
w_en: bool,
w_data: (u8, i8),
w_mask: (bool, bool),
}
let io_cycles = [IO {
r_addr: 0,
r_en: false,
r_data: (0, 0),
w_addr: 0,
w_en: false,
w_data: (0, 0),
w_mask: (false, false),
}];
for (
cycle,
expected @ IO {
r_addr,
r_en,
r_data: _,
w_addr,
w_en,
w_data,
w_mask,
},
) in io_cycles.into_iter().enumerate()
{
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);
sim.write_bool_or_int(sim.io().w.data.0, w_data.0);
sim.write_bool_or_int(sim.io().w.data.1, w_data.1);
sim.write_bool(sim.io().w.mask.0, w_mask.0);
sim.write_bool(sim.io().w.mask.1, w_mask.1);
let io = IO {
r_addr,
r_en,
r_data: (
sim.read_bool_or_int(sim.io().r.data.0)
.to_bigint()
.try_into()
.expect("known to be in range"),
sim.read_bool_or_int(sim.io().r.data.1)
.to_bigint()
.try_into()
.expect("known to be in range"),
),
w_addr,
w_en,
w_data,
w_mask,
};
assert_eq!(
expected,
io,
"cycle: {cycle}\nvcd:\n{}",
String::from_utf8(writer.take()).unwrap(),
);
sim.advance_time(SimDuration::from_micros(1));
sim.write_clock(sim.io().r.clk, true);
sim.write_clock(sim.io().w.clk, true);
sim.advance_time(SimDuration::from_micros(1));
sim.write_clock(sim.io().r.clk, false);
sim.write_clock(sim.io().w.clk, false);
}
sim.flush_traces().unwrap();
let vcd = String::from_utf8(writer.take()).unwrap();
println!("####### VCD:\n{vcd}\n#######");
if vcd != include_str!("sim/expected/memories.vcd") {
panic!();
}
let sim_debug = format!("{sim:#?}");
println!("#######\n{sim_debug}\n#######");
if sim_debug != include_str!("sim/expected/memories.txt") {
panic!();
}
}
// TODO: add more tests for memories

View file

@ -47,6 +47,7 @@ Simulation {
..
},
pc: 2,
memory_write_log: [],
memories: StatePart {
value: [],
},
@ -112,7 +113,7 @@ Simulation {
TraceModuleIO {
name: "o",
child: TraceUInt {
id: TraceScalarId(0),
location: TraceScalarId(0),
name: "o",
ty: UInt<8>,
flow: Sink,
@ -133,6 +134,7 @@ Simulation {
last_state: 0x05,
},
],
trace_memories: {},
trace_writers: [],
instant: 0 s,
clocks_triggered: [],

View file

@ -73,6 +73,7 @@ Simulation {
..
},
pc: 5,
memory_write_log: [],
memories: StatePart {
value: [],
},
@ -175,7 +176,7 @@ Simulation {
TraceModuleIO {
name: "reset_out",
child: TraceAsyncReset {
id: TraceScalarId(0),
location: TraceScalarId(0),
name: "reset_out",
flow: Sink,
},
@ -185,7 +186,7 @@ Simulation {
TraceModuleIO {
name: "bit_out",
child: TraceBool {
id: TraceScalarId(1),
location: TraceScalarId(1),
name: "bit_out",
flow: Sink,
},
@ -212,6 +213,7 @@ Simulation {
last_state: 0x1,
},
],
trace_memories: {},
trace_writers: [
Running(
VcdWriter {

View file

@ -168,6 +168,7 @@ Simulation {
..
},
pc: 18,
memory_write_log: [],
memories: StatePart {
value: [],
},
@ -417,12 +418,12 @@ Simulation {
name: "cd",
fields: [
TraceClock {
id: TraceScalarId(0),
location: TraceScalarId(0),
name: "clk",
flow: Source,
},
TraceAsyncReset {
id: TraceScalarId(1),
location: TraceScalarId(1),
name: "rst",
flow: Source,
},
@ -446,7 +447,7 @@ Simulation {
TraceModuleIO {
name: "count",
child: TraceUInt {
id: TraceScalarId(2),
location: TraceScalarId(2),
name: "count",
ty: UInt<4>,
flow: Sink,
@ -457,7 +458,7 @@ Simulation {
TraceReg {
name: "count_reg",
child: TraceUInt {
id: TraceScalarId(3),
location: TraceScalarId(3),
name: "count_reg",
ty: UInt<4>,
flow: Duplex,
@ -502,6 +503,7 @@ Simulation {
last_state: 0x3,
},
],
trace_memories: {},
trace_writers: [
Running(
VcdWriter {

View file

@ -150,6 +150,7 @@ Simulation {
..
},
pc: 15,
memory_write_log: [],
memories: StatePart {
value: [],
},
@ -398,12 +399,12 @@ Simulation {
name: "cd",
fields: [
TraceClock {
id: TraceScalarId(0),
location: TraceScalarId(0),
name: "clk",
flow: Source,
},
TraceSyncReset {
id: TraceScalarId(1),
location: TraceScalarId(1),
name: "rst",
flow: Source,
},
@ -427,7 +428,7 @@ Simulation {
TraceModuleIO {
name: "count",
child: TraceUInt {
id: TraceScalarId(2),
location: TraceScalarId(2),
name: "count",
ty: UInt<4>,
flow: Sink,
@ -438,7 +439,7 @@ Simulation {
TraceReg {
name: "count_reg",
child: TraceUInt {
id: TraceScalarId(3),
location: TraceScalarId(3),
name: "count_reg",
ty: UInt<4>,
flow: Duplex,
@ -483,6 +484,7 @@ Simulation {
last_state: 0x3,
},
],
trace_memories: {},
trace_writers: [
Running(
VcdWriter {

View file

@ -875,6 +875,7 @@ Simulation {
..
},
pc: 100,
memory_write_log: [],
memories: StatePart {
value: [],
},
@ -1333,12 +1334,12 @@ Simulation {
name: "cd",
fields: [
TraceClock {
id: TraceScalarId(0),
location: TraceScalarId(0),
name: "clk",
flow: Source,
},
TraceSyncReset {
id: TraceScalarId(1),
location: TraceScalarId(1),
name: "rst",
flow: Source,
},
@ -1362,7 +1363,7 @@ Simulation {
TraceModuleIO {
name: "en",
child: TraceBool {
id: TraceScalarId(2),
location: TraceScalarId(2),
name: "en",
flow: Source,
},
@ -1372,7 +1373,7 @@ Simulation {
TraceModuleIO {
name: "which_in",
child: TraceUInt {
id: TraceScalarId(3),
location: TraceScalarId(3),
name: "which_in",
ty: UInt<2>,
flow: Source,
@ -1383,7 +1384,7 @@ Simulation {
TraceModuleIO {
name: "data_in",
child: TraceUInt {
id: TraceScalarId(4),
location: TraceScalarId(4),
name: "data_in",
ty: UInt<4>,
flow: Source,
@ -1394,7 +1395,7 @@ Simulation {
TraceModuleIO {
name: "which_out",
child: TraceUInt {
id: TraceScalarId(5),
location: TraceScalarId(5),
name: "which_out",
ty: UInt<2>,
flow: Sink,
@ -1405,7 +1406,7 @@ Simulation {
TraceModuleIO {
name: "data_out",
child: TraceUInt {
id: TraceScalarId(6),
location: TraceScalarId(6),
name: "data_out",
ty: UInt<4>,
flow: Sink,
@ -1418,7 +1419,7 @@ Simulation {
child: TraceEnumWithFields {
name: "the_reg",
discriminant: TraceEnumDiscriminant {
id: TraceScalarId(7),
location: TraceScalarId(7),
name: "$tag",
ty: Enum {
A,
@ -1432,13 +1433,13 @@ Simulation {
name: "B",
fields: [
TraceUInt {
id: TraceScalarId(8),
location: TraceScalarId(8),
name: "0",
ty: UInt<1>,
flow: Source,
},
TraceBool {
id: TraceScalarId(9),
location: TraceScalarId(9),
name: "1",
flow: Source,
},
@ -1458,13 +1459,13 @@ Simulation {
name: "a",
elements: [
TraceUInt {
id: TraceScalarId(10),
location: TraceScalarId(10),
name: "[0]",
ty: UInt<1>,
flow: Source,
},
TraceUInt {
id: TraceScalarId(11),
location: TraceScalarId(11),
name: "[1]",
ty: UInt<1>,
flow: Source,
@ -1474,7 +1475,7 @@ Simulation {
flow: Source,
},
TraceSInt {
id: TraceScalarId(12),
location: TraceScalarId(12),
name: "b",
ty: SInt<2>,
flow: Source,
@ -1623,6 +1624,7 @@ Simulation {
last_state: 0x3,
},
],
trace_memories: {},
trace_writers: [
Running(
VcdWriter {

View file

@ -180,6 +180,7 @@ Simulation {
..
},
pc: 17,
memory_write_log: [],
memories: StatePart {
value: [],
},
@ -531,25 +532,25 @@ Simulation {
name: "o",
fields: [
TraceUInt {
id: TraceScalarId(0),
location: TraceScalarId(0),
name: "i",
ty: UInt<4>,
flow: Source,
},
TraceSInt {
id: TraceScalarId(1),
location: TraceScalarId(1),
name: "o",
ty: SInt<2>,
flow: Sink,
},
TraceSInt {
id: TraceScalarId(2),
location: TraceScalarId(2),
name: "i2",
ty: SInt<2>,
flow: Source,
},
TraceUInt {
id: TraceScalarId(3),
location: TraceScalarId(3),
name: "o2",
ty: UInt<4>,
flow: Sink,
@ -585,25 +586,25 @@ Simulation {
name: "child",
fields: [
TraceUInt {
id: TraceScalarId(8),
location: TraceScalarId(8),
name: "i",
ty: UInt<4>,
flow: Sink,
},
TraceSInt {
id: TraceScalarId(9),
location: TraceScalarId(9),
name: "o",
ty: SInt<2>,
flow: Source,
},
TraceSInt {
id: TraceScalarId(10),
location: TraceScalarId(10),
name: "i2",
ty: SInt<2>,
flow: Sink,
},
TraceUInt {
id: TraceScalarId(11),
location: TraceScalarId(11),
name: "o2",
ty: UInt<4>,
flow: Source,
@ -627,7 +628,7 @@ Simulation {
TraceModuleIO {
name: "i",
child: TraceUInt {
id: TraceScalarId(4),
location: TraceScalarId(4),
name: "i",
ty: UInt<4>,
flow: Source,
@ -638,7 +639,7 @@ Simulation {
TraceModuleIO {
name: "o",
child: TraceSInt {
id: TraceScalarId(5),
location: TraceScalarId(5),
name: "o",
ty: SInt<2>,
flow: Sink,
@ -649,7 +650,7 @@ Simulation {
TraceModuleIO {
name: "i2",
child: TraceSInt {
id: TraceScalarId(6),
location: TraceScalarId(6),
name: "i2",
ty: SInt<2>,
flow: Source,
@ -660,7 +661,7 @@ Simulation {
TraceModuleIO {
name: "o2",
child: TraceUInt {
id: TraceScalarId(7),
location: TraceScalarId(7),
name: "o2",
ty: UInt<4>,
flow: Sink,
@ -793,6 +794,7 @@ Simulation {
last_state: 0xe,
},
],
trace_memories: {},
trace_writers: [
Running(
VcdWriter {

View file

@ -227,6 +227,7 @@ Simulation {
..
},
pc: 30,
memory_write_log: [],
memories: StatePart {
value: [],
},
@ -513,12 +514,12 @@ Simulation {
name: "cd",
fields: [
TraceClock {
id: TraceScalarId(0),
location: TraceScalarId(0),
name: "clk",
flow: Source,
},
TraceSyncReset {
id: TraceScalarId(1),
location: TraceScalarId(1),
name: "rst",
flow: Source,
},
@ -542,7 +543,7 @@ Simulation {
TraceModuleIO {
name: "d",
child: TraceBool {
id: TraceScalarId(2),
location: TraceScalarId(2),
name: "d",
flow: Source,
},
@ -552,7 +553,7 @@ Simulation {
TraceModuleIO {
name: "q",
child: TraceBool {
id: TraceScalarId(3),
location: TraceScalarId(3),
name: "q",
flow: Sink,
},
@ -562,7 +563,7 @@ Simulation {
TraceReg {
name: "reg0",
child: TraceBool {
id: TraceScalarId(4),
location: TraceScalarId(4),
name: "reg0",
flow: Duplex,
},
@ -571,7 +572,7 @@ Simulation {
TraceReg {
name: "reg1",
child: TraceBool {
id: TraceScalarId(5),
location: TraceScalarId(5),
name: "reg1",
flow: Duplex,
},
@ -580,7 +581,7 @@ Simulation {
TraceReg {
name: "reg2",
child: TraceBool {
id: TraceScalarId(6),
location: TraceScalarId(6),
name: "reg2",
flow: Duplex,
},
@ -589,7 +590,7 @@ Simulation {
TraceReg {
name: "reg3",
child: TraceBool {
id: TraceScalarId(7),
location: TraceScalarId(7),
name: "reg3",
flow: Duplex,
},
@ -663,6 +664,7 @@ Simulation {
last_state: 0x0,
},
],
trace_memories: {},
trace_writers: [
Running(
VcdWriter {