use rust_hdl::prelude::*; #[derive(LogicBlock)] struct RAMTest { pub clock: Signal, pub ram: RAM, 5>, } impl RAMTest { pub fn new() -> RAMTest { Self { clock: Signal::default(), ram: RAM::new(Default::default()), } } } impl Logic for RAMTest { #[hdl_gen] fn update(&mut self) { self.ram.write_clock.next = self.clock.val(); self.ram.read_clock.next = self.clock.val(); } } #[test] fn test_synthesis_ram() { let mut uut = RAMTest::new(); uut.ram.write_enable.connect(); uut.ram.write_data.connect(); uut.ram.write_address.connect(); uut.ram.read_address.connect(); uut.connect_all(); let vlog = generate_verilog(&uut); yosys_validate("ram_2", &vlog).unwrap(); } #[test] fn test_ram_works() { let mut uut = RAMTest::new(); uut.ram.write_enable.connect(); uut.ram.write_data.connect(); uut.ram.write_address.connect(); uut.ram.read_address.connect(); uut.connect_all(); yosys_validate("ram", &generate_verilog(&uut)).unwrap(); let mut sim = Simulation::new(); let rdata = (0..32) .map(|_| rand::random::().to_bits()) .collect::>(); sim.add_clock(5, |x: &mut Box| x.clock.next = !x.clock.val()); sim.add_testbench(move |mut sim: Sim| { println!("Init test bench"); let mut x = sim.init()?; wait_clock_true!(sim, clock, x); for sample in rdata.iter().enumerate() { x.ram.write_address.next = sample.0.to_bits(); x.ram.write_data.next = *sample.1; x.ram.write_enable.next = true; wait_clock_cycle!(sim, clock, x); } x.ram.write_enable.next = false.into(); wait_clock_cycle!(sim, clock, x); for sample in rdata.iter().enumerate() { x.ram.read_address.next = sample.0.to_bits(); wait_clock_cycle!(sim, clock, x); assert_eq!(x.ram.read_data.val(), *sample.1); } sim.done(x)?; Ok(()) }); sim.run_traced( Box::new(uut), 512 * 10, std::fs::File::create(vcd_path!("ram.vcd")).unwrap(), ) .unwrap(); }