util

JoinDomains #(T1, T2, int OFFSET)

module JoinDomains #(T1, T2, int OFFSET) {
    interface identity1 : T1 i1'0 -> T1 o1'0
    interface identity2 : T2 i2'OFFSET -> T2 o2'OFFSET
}

SlowClockGenerator #(int PERIOD)

module SlowClockGenerator #(int PERIOD) {
    interface SlowClockGenerator : -> int cur_value
}

Abs #(int TO)

module Abs #(int TO) {
    interface Abs : int #(FROM: -TO+1, TO) a -> int #(FROM: 0, TO) o
}

Repeat #(T, int SIZE)

Returns an array of SIZE copies of v - should not consume any hardware Runtime version of RepeatGen

module Repeat #(T, int SIZE) {
    interface Repeat : T v'0 -> T[SIZE] result'0
}

Reverse #(T, int SIZE)

Reverse an array - should not consume any hardware Runtime version of ReverseGen

module Reverse #(T, int SIZE) {
    interface Reverse : T[SIZE] v'0 -> T[SIZE] result'0
}

Concat #(T, int SIZE_A, int SIZE_B)

Concatenate two arrays, such that the elements of b come after the elements of a - should not consume any hardware Runtime version of ConcatGen

module Concat #(T, int SIZE_A, int SIZE_B) {
    interface Concat : T[SIZE_A] a'0, T[SIZE_B] b'0 -> T[SIZE_A + SIZE_B] result'0
}

BitSelect #(int SIZE)

module BitSelect #(int SIZE) {
    interface BitSelect : int#(FROM: 0, TO: SIZE - 1) selection'0 -> bool[SIZE] bits'0
}

PopCount #(int WIDTH)

module PopCount #(int WIDTH) {
    interface PopCount : bool[WIDTH] bits'0 -> int#(FROM: 0, TO: WIDTH+1) popcount
}

TreeAdd #(int WIDTH, int FROM, int TO)

module TreeAdd #(int WIDTH, int FROM, int TO) {
    interface TreeAdd : int#(FROM, TO)[WIDTH] values'0 -> int#(FROM: FROM*WIDTH, TO: (TO - 1)*WIDTH + 1) total
}

BitwiseIntSplit #(int TO, int LOWER_BITS)

Splits the given integer. The upper LOWER_BITS: bits are returned as upper, the lower :LOWER_BITS bits are returned in lower See also BitwiseIntConcat

module BitwiseIntSplit #(int TO, int LOWER_BITS) {
    interface BitwiseIntSplit : int#(FROM: 0, TO) v'0 -> int#(FROM: 0, TO: UPPER_TO) upper'0, int#(FROM: 0, TO: pow2#(E: LOWER_BITS)) lower'0
}

BitwiseIntConcat #(int UPPER_TO, int LOWER_BITS)

Recombines a lower and upper integer parts. See also BitwiseIntSplit

module BitwiseIntConcat #(int UPPER_TO, int LOWER_BITS) {
    interface BitwiseIntConcat : int#(FROM: 0, TO: UPPER_TO) upper'0, int#(FROM: 0, TO: pow2#(E: LOWER_BITS)) lower'0 -> int#(FROM: 0, TO: UPPER_TO * pow2#(E: LOWER_BITS)) v'0
}

AlignToPow2 #(int FROM, int TO, int LOWER_BITS)

Sets the lower :LOWER_BITS bits to false, thus aligning the value Works for unsigned and signed integers alike

module AlignToPow2 #(int FROM, int TO, int LOWER_BITS) {
    interface AlignToPow2 : int#(FROM, TO) i'0 -> int#(FROM: ALIGNED_FROM, TO: ALIGNED_TO) o'0
}

IntToBool

Converts a '0' or '1' into the equivalent boolean 'false' or 'true' respectively

module IntToBool {
    interface IntToBool : int#(FROM: 0, TO: 2) i'0 -> bool o'0
}

BoolToInt

Converts a 'false' or 'true' into the equivalent integer '0' or '1' respectively

module BoolToInt {
    interface BoolToInt : bool i'0 -> int#(FROM: 0, TO: 2) o'0
}

Ternary #(T)

Equivalent to the C/Verilog cond ? a : b ternary operator. When cond is true it returns a, otherwise it returns b

module Ternary #(T) {
    interface Ternary : bool cond'0, T a'0, T b'0 -> T o'0
}

RotateLeft #(T, int ARRAY_LEN)

Rotates towards lower indexes by the provided offset. Implemented as a Barrel Shifter

Example: RotateLeft([1, 2, 3, 4], 1) == [2, 3, 4, 1]

module RotateLeft #(T, int ARRAY_LEN) {
    interface RotateLeft : T[ARRAY_LEN] data'0, int#(FROM: 0, TO: ARRAY_LEN) offset'0 -> T[ARRAY_LEN] rotated_data'0
}

RotateRight #(T, int ARRAY_LEN)

Rotates towards higher indexes by the provided offset. Implemented as a Barrel Shifter

Example: RotateRight([1, 2, 3, 4], 1) == [4, 1, 2, 3]

module RotateRight #(T, int ARRAY_LEN) {
    interface RotateRight : T[ARRAY_LEN] data'0, int#(FROM: 0, TO: ARRAY_LEN) offset'0 -> T[ARRAY_LEN] rotated_data'0
}

Tuple2 #(T1, T2)

Temporary module for creating and deconstructing tuples, until we have structs

module Tuple2 #(T1, T2) {
    clock clk
    interface pack : T1 v1_i'0, T2 v2_i'0 -> bool[TO2] packed_o'0
    interface unpack : bool[TO2] packed_i'0 -> T1 v1_o'0, T2 v2_o'0
}

Tuple3 #(T1, T2, T3)

Temporary module for creating and deconstructing tuples, until we have structs

module Tuple3 #(T1, T2, T3) {
    clock clk
    interface pack : T1 v1_i'0, T2 v2_i'0, T3 v3_i'0 -> bool[TO3] packed_o'0
    interface unpack : bool[TO3] packed_i'0 -> T1 v1_o'0, T2 v2_o'0, T3 v3_o'0
}

Tuple4 #(T1, T2, T3, T4)

Temporary module for creating and deconstructing tuples, until we have structs

module Tuple4 #(T1, T2, T3, T4) {
    clock clk
    interface pack : T1 v1_i'0, T2 v2_i'0, T3 v3_i'0, T4 v4_i'0 -> bool[TO4] packed_o'0
    interface unpack : bool[TO4] packed_i'0 -> T1 v1_o'0, T2 v2_o'0, T3 v3_o'0, T4 v4_o'0
}

Tuple5 #(T1, T2, T3, T4, T5)

Temporary module for creating and deconstructing tuples, until we have structs

module Tuple5 #(T1, T2, T3, T4, T5) {
    clock clk
    interface pack : T1 v1_i'0, T2 v2_i'0, T3 v3_i'0, T4 v4_i'0, T5 v5_i'0 -> bool[TO5] packed_o'0
    interface unpack : bool[TO5] packed_i'0 -> T1 v1_o'0, T2 v2_o'0, T3 v3_o'0, T4 v4_o'0, T5 v5_o'0
}

RippleFIFO #(T, int DEPTH)

A FIFO implemented as a sequence of registers with a accompanying valid bit.

Bandwidth limited to 1 element every 2 cycles.

Use for very small FIFOs, in bandwidth-limited circumstances.

module RippleFIFO #(T, int DEPTH) {
    clock clk
    output bool may_push'0
    action push'0 : T push_data'0
    output bool may_pop'0
    action pop'0 : -> T pop_data'0
    action rst
}