ferrilator

Crates.ioferrilator
lib.rsferrilator
version0.5.0
created_at2025-09-08 11:49:29.869623+00
updated_at2025-10-16 21:54:20.480149+00
descriptionA tool intended to simplify writing Verilator tests in Rust.
homepagehttps://github.com/toshaf/ferrilator
repositoryhttps://github.com/toshaf/ferrilator
max_upload_size
id1829205
size14,363
toshaf (toshaf)

documentation

README

Ferrilator

For writing Verilator tests in Rust.

There are two main parts; binding generation and build orchestration.

Bindings for your top module can be generated like this:

use ferrilator::attr::ferrilate;

#[ferrilate(counter)]
struct Counter {
    #[clock]
    #[input]
    clk: bool,

    #[input]
    reset: bool,

    #[input]
    enable: bool,

    #[output]
    value: u8,

    #[output]
    overflow: bool,
}

and tests can then be written like this:

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_counter() {
        let mut dut = Counter::new();
        dut.set_enable(true);

        dut.tick();
        assert_eq!(0, dut.get_value());
        assert_eq!(false, dut.get_overflow());

        dut.tick();
        assert_eq!(1, dut.get_value());
        assert_eq!(false, dut.get_overflow());

        dut.tick();
        assert_eq!(2, dut.get_value());
        assert_eq!(false, dut.get_overflow());

        dut.set_reset(true);
        dut.tick();
        assert_eq!(0, dut.get_value());
        assert_eq!(false, dut.get_overflow());

        dut.set_reset(false);
        dut.set_enable(false);

        for _ in 0..10 {
            dut.tick();
            assert_eq!(0, dut.get_value());
            assert_eq!(false, dut.get_overflow());
        }

        dut.set_enable(true);

        for i in 0..255 {
            assert_eq!(i, dut.get_value());
            assert_eq!(false, dut.get_overflow());
            dut.tick();
        }

        dut.tick();
        assert_eq!(0, dut.get_value());
        assert_eq!(true, dut.get_overflow());

        dut.tick();
        assert_eq!(1, dut.get_value());
        assert_eq!(false, dut.get_overflow());
    }
}

The full Verilator build can be run from your build.rs like this:


fn main() {
    ferrilator::build("Counter", "src/counter.rs", &["src/hdl/counter.sv"]).unwrap();
}

Commit count: 4

cargo fmt