forked from libre-chip/fayalite
sim: add WIP memory test
This commit is contained in:
parent
8616ee4737
commit
393f78a14d
11 changed files with 1155 additions and 304 deletions
|
@ -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
|
||||
|
|
|
@ -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: [],
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue