Module delay

Source
Expand description

A component that adds delay_ticks between receiving anything and sending it on to its output.

The Delay can be configured such that it will return an error if the output is ever blocked. Otherwise it will implicitly assert back-pressure on the input.

§Ports

This component has the following ports:

§Function

Fundamentally the Delay’s functionality is to:

loop {
    let value = rx.get()?.await;
    clock.wait_ticks(delay_ticks).await;
    tx.put(value)?.await;
}

However, the problem with this is that the input ends up being blocked if the output does not instantly consume the value. Therefore the Delay is actually split into two halves that manage the ports independently.

§Input

A simplified view of how the input side works is:

loop {
    // Receive value from input
    let value = rx.get()?.await;

    // Compute time at which it should leave Delay
    let mut tick = clock.tick_now();
    tick.set_tick(tick.tick() + delay_ticks as u64);

    // Send to the output side
    pending.borrow_mut().push_back((value, tick));

    // Wake up output if required
    pending_changed.notify()?;
}

§Output

A simplified view of how the output side works is:

loop {
    // Get next value and tick at which to send value
    if let Some((value, tick)) = pending.borrow_mut().pop_front() {
        // Wait for correct time
        let tick_now = clock.tick_now();
        clock.wait_ticks(tick.tick() - tick_now.tick()).await;

        // Send value
        tx.put(value)?.await;
    } else {
        // Wait to be notified of new data
        pending_changed.listen().await;
    }
}

§Using a Delay

A Delay simply needs to be created with the latency through it and connected between components.

    // Create the components
    let source = Source::new_and_register(&engine, top, "source", to_send)?;
    let delay = Delay::new_and_register(&engine, &clock, top, "delay", delay_ticks)?;
    let sink = Sink::new_and_register(&engine, &clock, top, "sink")?;

    // Connect the ports
    connect_port!(source, tx => delay, rx)?;
    connect_port!(delay, tx => sink, rx)?;

    run_simulation!(engine);

Structs§

Delay