use rust_hdl::prelude::*; #[derive(LogicBlock)] struct ReducerTest { pub clock: Signal, pub fifo_in: SynchronousFIFO, 4, 5, 1>, pub fifo_out: SynchronousFIFO, 8, 9, 1>, pub redux: FIFOReducerN<32, 4>, } impl Logic for ReducerTest { #[hdl_gen] fn update(&mut self) { clock!(self, clock, fifo_in, fifo_out, redux); self.redux.empty.next = self.fifo_in.empty.val(); self.redux.data_in.next = self.fifo_in.data_out.val(); self.fifo_in.read.next = self.redux.read.val(); self.redux.full.next = self.fifo_out.full.val(); self.fifo_out.data_in.next = self.redux.data_out.val(); self.fifo_out.write.next = self.redux.write.val(); } } impl ReducerTest { pub fn new(order: WordOrder) -> Self { Self { clock: Default::default(), fifo_in: Default::default(), fifo_out: Default::default(), redux: FIFOReducerN::new(order), } } } #[test] fn test_reducer_works() { let mut uut = ReducerTest::new(WordOrder::MostSignificantFirst); uut.fifo_in.data_in.connect(); uut.fifo_in.write.connect(); uut.fifo_out.read.connect(); uut.connect_all(); let mut sim = Simulation::new(); sim.add_clock(5, |x: &mut Box| x.clock.next = !x.clock.val()); sim.add_testbench(move |mut sim: Sim| { let mut x = sim.init()?; wait_clock_true!(sim, clock, x); for datum in [0xDEADBEEF, 0xCAFEBABE] { x = sim.watch(|x| !x.fifo_in.full.val(), x)?; x.fifo_in.data_in.next = datum.into(); x.fifo_in.write.next = true; wait_clock_cycle!(sim, clock, x); x.fifo_in.write.next = false; } sim.done(x) }); sim.add_testbench(move |mut sim: Sim| { let mut x = sim.init()?; wait_clock_true!(sim, clock, x); for datum in [ 0xD, 0xE, 0xA, 0xD, 0xB, 0xE, 0xE, 0xF, 0xC, 0xA, 0xF, 0xE, 0xB, 0xA, 0xB, 0xE, ] { x = sim.watch(|x| !x.fifo_out.empty.val(), x)?; sim_assert!(sim, x.fifo_out.data_out.val() == Bits::<4>::from(datum), x); x.fifo_out.read.next = true; wait_clock_cycle!(sim, clock, x); x.fifo_out.read.next = false; } sim.done(x) }); sim.run(Box::new(uut), 100_000).unwrap() } #[test] fn test_reducer_works_least_sig_word_first() { let mut uut = ReducerTest::new(WordOrder::LeastSignificantFirst); uut.fifo_in.data_in.connect(); uut.fifo_in.write.connect(); uut.fifo_out.read.connect(); uut.connect_all(); let mut sim = Simulation::new(); sim.add_clock(5, |x: &mut Box| x.clock.next = !x.clock.val()); sim.add_testbench(move |mut sim: Sim| { let mut x = sim.init()?; wait_clock_true!(sim, clock, x); for datum in [0xFEEBDAED, 0xEBABEFAC] { x = sim.watch(|x| !x.fifo_in.full.val(), x)?; x.fifo_in.data_in.next = datum.into(); x.fifo_in.write.next = true; wait_clock_cycle!(sim, clock, x); x.fifo_in.write.next = false; } sim.done(x) }); sim.add_testbench(move |mut sim: Sim| { let mut x = sim.init()?; wait_clock_true!(sim, clock, x); for datum in [ 0xD, 0xE, 0xA, 0xD, 0xB, 0xE, 0xE, 0xF, 0xC, 0xA, 0xF, 0xE, 0xB, 0xA, 0xB, 0xE, ] { x = sim.watch(|x| !x.fifo_out.empty.val(), x)?; sim_assert!(sim, x.fifo_out.data_out.val() == Bits::<4>::from(datum), x); x.fifo_out.read.next = true; wait_clock_cycle!(sim, clock, x); x.fifo_out.read.next = false; } sim.done(x) }); sim.run(Box::new(uut), 100_000).unwrap() } declare_narrowing_fifo!(Slim, 32, 16, 4, 256); #[derive(LogicBlock)] struct SlimTest { pub clock: Signal, pub fifo: Slim, } impl Logic for SlimTest { #[hdl_gen] fn update(&mut self) { self.fifo.write_clock.next = self.clock.val(); self.fifo.read_clock.next = self.clock.val(); } } impl SlimTest { pub fn new(order: WordOrder) -> Self { Self { clock: Default::default(), fifo: Slim::new(order), } } } #[test] fn test_slim_works() { let mut uut = SlimTest::new(WordOrder::MostSignificantFirst); uut.fifo.data_in.connect(); uut.fifo.write.connect(); uut.fifo.read.connect(); uut.connect_all(); let mut sim = Simulation::new(); sim.add_clock(5, |x: &mut Box| x.clock.next = !x.clock.val()); sim.add_testbench(move |mut sim: Sim| { let mut x = sim.init()?; wait_clock_true!(sim, clock, x); for datum in [0xDEADBEEF, 0xCAFEBABE] { x = sim.watch(|x| !x.fifo.full.val(), x)?; x.fifo.data_in.next = datum.into(); x.fifo.write.next = true; wait_clock_cycle!(sim, clock, x); x.fifo.write.next = false; } sim.done(x) }); sim.add_testbench(move |mut sim: Sim| { let mut x = sim.init()?; wait_clock_true!(sim, clock, x); for datum in [ 0xD, 0xE, 0xA, 0xD, 0xB, 0xE, 0xE, 0xF, 0xC, 0xA, 0xF, 0xE, 0xB, 0xA, 0xB, 0xE, ] { x = sim.watch(|x| !x.fifo.empty.val(), x)?; sim_assert!(sim, x.fifo.data_out.val() == Bits::<4>::from(datum), x); x.fifo.read.next = true; wait_clock_cycle!(sim, clock, x); x.fifo.read.next = false; } sim.done(x) }); sim.run(Box::new(uut), 100_000).unwrap() }