::core::

Primitive inv

Expand

Values which flow in the opposite direction to normal values.

Spade code is “linear”: units take inputs and produce outputs. However, sometimes one wants to return a wire to which another module can assign a value, or accept an input where a value can be assigned.

This is what inv is used for. Accepting an inv T as an input lets the unit assign a value to the wires being passed in, while returning an inv T returns a wire to which another unit can assign a value.

inv is also more general, it flips the direction of any signals it is applied to. inv inv T is the same as T, and inv (inv T, T) is the same as (T, inv T).

For more details in inverted wires, refer to the book.

Implementations

impl<T, #uint N> inv [T; N]
fn transpose(self) -> [inv T; N]

Transposes an inv array into an array of inv values.

This transformation preserves the low level signals behind the value, but presents them in a new format that is easier to destructure.

Examples

let a = port;
let inv_array: inv [bool; 2] = a.1;
let array_of_invs: [inv bool; 2] = inv_array.transpose();
set array_of_invs[0] = true;
set array_of_invs[1] = false;
assert a.0 == [true, false];
impl<T> inv T
pub fn inspect(self) -> (T, Self)

Retrieves the contents of an inv wire alongside a copy of itself.

Most of the time port should be preferred, as it provides both directions at the same place and those can be passed around wherever they are needed. But sometimes, passing the forward value along through a deep hierarchy to where it is needed pollutes type signatures for little benefit. As a practical solution, (inv T)::inspect can be used instead to tap into an existing inv wire by connecting a new port to it, consuming it and getting both the forward value and a fresh inv value.

Examples

let (fwd, back) = port;
let (new_fwd, new_back) = back.inspect();
set new_back = true;
assert fwd == true;
assert new_fwd == true;