rust-hdl 0.46.0

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

#[derive(LogicBlock)]
struct FIFOBridgeTest {
    feeder: LazyFIFOFeeder<Bits<8>, 12>,
    fp: SyncFIFO<Bits<8>, 4, 5, 1>,
    bp: SyncFIFO<Bits<8>, 4, 5, 1>,
    reader: LazyFIFOReader<Bits<8>, 12>,
    lnk: FIFOLink<Bits<8>>,
    clock: Signal<In, Clock>,
}

impl Logic for FIFOBridgeTest {
    #[hdl_gen]
    fn update(&mut self) {
        clock!(self, clock, fp, bp, reader, feeder);
        FIFOWriteController::<Bits<8>>::join(&mut self.feeder.bus, &mut self.fp.bus_write);
        FIFOReadResponder::<Bits<8>>::join(&mut self.fp.bus_read, &mut self.lnk.read);
        FIFOWriteController::<Bits<8>>::join(&mut self.lnk.write, &mut self.bp.bus_write);
        FIFOReadResponder::<Bits<8>>::join(&mut self.bp.bus_read, &mut self.reader.bus);
    }
}

impl Default for FIFOBridgeTest {
    fn default() -> Self {
        let data1 = (0..256)
            .map(|_| rand::thread_rng().gen::<u8>().to_bits())
            .collect::<Vec<_>>();
        let data2 = data1.clone();
        Self {
            feeder: LazyFIFOFeeder::new(&data2, &bursty_vec(256)),
            fp: Default::default(),
            bp: Default::default(),
            reader: LazyFIFOReader::new(&data1, &bursty_vec(256)),
            lnk: Default::default(),
            clock: Default::default(),
        }
    }
}

#[test]
fn test_fifo_linker() {
    let mut uut = FIFOBridgeTest::default();
    uut.clock.connect();
    uut.feeder.start.connect();
    uut.reader.start.connect();
    uut.connect_all();
    let mut sim = Simulation::new();
    sim.add_clock(5, |x: &mut Box<FIFOBridgeTest>| {
        x.clock.next = !x.clock.val()
    });
    sim.add_testbench(move |mut sim: Sim<FIFOBridgeTest>| {
        let mut x = sim.init()?;
        wait_clock_true!(sim, clock, x);
        x.feeder.start.next = true;
        x.reader.start.next = true;
        wait_clock_cycle!(sim, clock, x);
        x.feeder.start.next = false;
        x.reader.start.next = false;
        x = sim.watch(|x| x.feeder.done.val() & x.reader.done.val(), x)?;
        wait_clock_cycle!(sim, clock, x);
        sim_assert!(sim, !x.reader.error.val(), x);
        sim.done(x)
    });
    sim.run_to_file(Box::new(uut), 100_000, &vcd_path!("hls_fifo_link.vcd"))
        .unwrap();
}