::ready_valid::

Struct Rv

pub struct Rv<T> {
data: Option<T>,
ready: inv bool,
}

Implementations

impl<T> Rv<T>
pub entity buffer(self, clk: clock, rst: bool) -> Rv<T>

Decouples the producer from the consumer by inserting a buffer register between them. This both allows producers and consumers to work in parallel, and also breaks the ready combinational path

However, this decoupling of the ready signal means that the throughput is at most 50% of the time, so for a high throughput stream, this should not be used

pub entity skid_buffer(self, clk: clock, rst: bool) -> Rv<T>
pub entity terminate_unready(self)
pub entity terminate_ready(self)
pub entity map<F, O>(self, f: F) -> Rv<O>
where
F: Fn(T) -> O,
pub entity and_then<F, O>(self, f: F) -> Rv<O>
where
F: Fn(T) -> Option<O>,
pub entity append_lower_priority(self, other: Rv<T>) -> Rv<T>
pub entity append_higher_priority(self, other: Rv<T>) -> Rv<T>
pub fn gate(self, gate: bool) -> Rv<T>

If gate is false, do not propagate any values

pub entity fsm<State, O>(self, clk: clock, rst: bool, first_state: impl Fn(T) -> State, update_fn: impl Fn(State) -> Option<State>, output_fn: impl Fn(State) -> O) -> Rv<O>

Runs an FSM on each value in the Rv.

The FSM is described by the three functions first_state, update_fn and output_fn. In the first cycle where a new value is present, the first_state function is invoked to convert the value into an internal state reprensetation. On subsequent cycles, the update_fn is called to transform the state. The update_fn returns Some(new_state) if the the value still needs further processing, and None if it is done processing.

When it is done processing, output_fn is used to transform the final state into an output value.

It takes one clock cycle for the FSM to start as the update_fn function is not invoked on the output of first_state.

It takes one clock cycle for a new value to be accepted by the FSM after the output has been accepted. The FSM can start processing new values even if the downstream is not ready, it will hold on to the output when the downstream is not ready.

impl<L> Rv<L>
fn join<R>(self, r: Rv<R>) -> Rv<(L, R)>
impl<L, R> Rv<(L, R)>
fn split_unbuffered(self) -> (Rv<L>, Rv<R>)

Split the Rv into two disjoint streams. Unlike split which contains buffers on the two streams, this requires both stream to have some buffer if they are to be joined later, otherwise they will deadlock.

entity split(self, clk: clock, rst: bool) -> (Rv<L>, Rv<R>)

Split the Rv into two disjoint streams where every element on self results in an element on the left and right streams.

Contains skid buffers on both streams which prevent deadlocks if the two streams are to be joined in the future. If both streams have buffers downstream, split_unbuffered can be used.

impl<T> Rv<T>
pub entity with_minimum_delay<#uint N>(self, clk: clock, rst: bool) -> Rv<T>

Enforces a delay of at least N clock cycles between transactions being completed by disconnecting the producer from the consumer for N cycles after a transaction has been accepted

impl<T> Rv<T>
pub entity cdc_fifo_buffer<#uint Depth>(self, write_clk: clock, write_rst: bool, read_clk: clock, read_rst: bool) -> FifoOut<T>

Buffers the values using a FIFO, which can be used to cross clock domains.

pub entity fifo_buffer<#uint Depth>(self, clk: clock, rst: bool) -> FifoOut<T>
impl Rv<uint<16>>
pub entity split_to_u8(self, clk: clock, rst: bool) -> Rv<uint<8>>
impl<T, #uint N> Rv<[T; N]>
pub entity into_element_stream(self, clk: clock, rst: bool) -> Rv<T>
impl Rv<Escaped<uint<8>>>
entity escape_bytes<F, #uint N>(self, clk: clock, rst: bool, escapees: [uint<8>; N], escape_fn: F, escape_prefix: uint<8>) -> Rv<uint<8>>
where
F: Fn(uint<8>) -> uint<8>,

Escapes bytes in the escapees list by first emitting an escape prefix, then emitting the the result of the escape_fn function on the escaped byte.

For example, the stream 1, 2, 3, 4 when called with escapees == [3] and escape_fn = fn (byte) {trunc(byte + 10)} and escape_prefix = 0 will result in 1 2 0 13 4