rust-hdl 0.46.0

Write firmware for FPGAs in Rust
Documentation
use rust_hdl::prelude::*;

#[derive(LogicBlock)]
struct RAMTest {
    pub clock: Signal<In, Clock>,
    pub ram: RAM<Bits<16>, 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::<u16>().to_bits())
        .collect::<Vec<_>>();
    sim.add_clock(5, |x: &mut Box<RAMTest>| x.clock.next = !x.clock.val());
    sim.add_testbench(move |mut sim: Sim<RAMTest>| {
        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();
}