use rust_hdl::prelude::*;
#[cfg(test)]
fn make_test_chip() -> SoCTestChip {
let mut uut = SoCTestChip::default();
uut.connect_all();
uut
}
#[test]
fn test_soc_chip_works() {
let uut = make_test_chip();
let mut sim = Simulation::new();
sim.add_clock(5, |x: &mut Box<SoCTestChip>| x.clock.next = !x.clock.val());
sim.add_clock(4, |x: &mut Box<SoCTestChip>| {
x.sys_clock.next = !x.sys_clock.val()
});
sim.add_testbench(move |mut sim: Sim<SoCTestChip>| {
let mut x = sim.init()?;
wait_clock_true!(sim, clock, x);
for iter in 0..10 {
wait_clock_cycles!(sim, clock, x, 20);
x.from_cpu.data.next = (0x0167 + iter).into();
x.from_cpu.write.next = true;
wait_clock_cycle!(sim, clock, x);
x.from_cpu.write.next = false;
wait_clock_cycles!(sim, clock, x, 5);
x.from_cpu.data.next = 0.into();
x.from_cpu.write.next = true;
wait_clock_cycle!(sim, clock, x);
x.from_cpu.write.next = false;
wait_clock_cycles!(sim, clock, x, 5);
}
sim.done(x)
});
sim.add_testbench(move |mut sim: Sim<SoCTestChip>| {
let mut x = sim.init()?;
wait_clock_true!(sim, clock, x);
for iter in 0..10 {
x = sim.watch(|x| !x.to_cpu.empty.val(), x)?;
sim_assert_eq!(sim, x.to_cpu.data.val(), (0x0167 + iter), x);
x.to_cpu.read.next = true;
wait_clock_cycle!(sim, clock, x);
x.to_cpu.read.next = false;
}
wait_clock_cycles!(sim, clock, x, 10);
sim.done(x)
});
sim.run_traced(
Box::new(uut),
5_000,
std::fs::File::create(vcd_path!("soc_chip_ping.vcd")).unwrap(),
)
.unwrap();
}
#[test]
fn test_soc_chip_read_write_works() {
let uut = make_test_chip();
let mut sim = Simulation::new();
sim.add_clock(5, |x: &mut Box<SoCTestChip>| x.clock.next = !x.clock.val());
sim.add_clock(4, |x: &mut Box<SoCTestChip>| {
x.sys_clock.next = !x.sys_clock.val()
});
let data_in = [0xDEAD, 0xBEEF, 0xCAFE, 0xBABE];
sim.add_testbench(move |mut sim: Sim<SoCTestChip>| {
let mut x = sim.init()?;
wait_clock_true!(sim, clock, x);
wait_clock_cycles!(sim, clock, x, 20);
x = sim.watch(|x| !x.from_cpu.full.val(), x)?;
x.from_cpu.data.next = 0x0300.into();
x.from_cpu.write.next = true;
wait_clock_cycle!(sim, clock, x);
x.from_cpu.write.next = false;
x = sim.watch(|x| !x.from_cpu.full.val(), x)?;
x.from_cpu.data.next = 0x0004.into();
x.from_cpu.write.next = true;
wait_clock_cycle!(sim, clock, x);
x.from_cpu.write.next = false;
for datum in data_in.clone() {
x = sim.watch(|x| !x.from_cpu.full.val(), x)?;
x.from_cpu.data.next = datum.into();
x.from_cpu.write.next = true;
wait_clock_cycle!(sim, clock, x);
x.from_cpu.write.next = false;
}
x = sim.watch(|x| !x.from_cpu.full.val(), x)?;
x.from_cpu.data.next = 0x0201.into();
x.from_cpu.write.next = true;
wait_clock_cycle!(sim, clock, x);
x.from_cpu.write.next = false;
x = sim.watch(|x| !x.from_cpu.full.val(), x)?;
x.from_cpu.data.next = 0x0004.into();
x.from_cpu.write.next = true;
wait_clock_cycle!(sim, clock, x);
x.from_cpu.write.next = false;
for datum in data_in.clone() {
x = sim.watch(|x| !x.to_cpu.empty.val(), x)?;
sim_assert_eq!(sim, x.to_cpu.data.val(), ((datum << 1) & 0xFFFF), x);
x.to_cpu.read.next = true;
wait_clock_cycle!(sim, clock, x);
x.to_cpu.read.next = false;
}
sim.done(x)
});
sim.run_traced(
Box::new(uut),
50_000,
std::fs::File::create(vcd_path!("soc_chip_pipe.vcd")).unwrap(),
)
.unwrap();
}