memory

ROM #(T, int DEPTH, T[DEPTH] DATA)

module ROM #(T, int DEPTH, T[DEPTH] DATA) {
    action read : int #(FROM: 0, TO: DEPTH) index'0 -> T output_data'1
}

RAM #(T, int DEPTH)

module RAM #(T, int DEPTH) {
    action write'0 : int#(FROM: 0, TO: DEPTH) write_addr'0, T write_data'0
    action read'0 : int#(FROM: 0, TO: DEPTH) read_addr'0 -> T read_data'1
}

RAM_Unbalanced #(ElemT, int DEPTH, int WRITE_SIZE, int READ_SIZE)

module RAM_Unbalanced #(ElemT, int DEPTH, int WRITE_SIZE, int READ_SIZE) {
    action write'0 : int#(FROM: 0, TO: DEPTH / WRITE_SIZE) write_addr'0, ElemT[WRITE_SIZE] write_data'0
    action read'0 : int#(FROM: 0, TO: DEPTH / READ_SIZE) read_addr'0 -> ElemT[READ_SIZE] read_data'1
}

ShiftReg #(T, int LATENCY)

This shift register is implemented as a memory block with a rotating index.

It is meant to bridge a long latency difference.

We keep one latency register on the inflow, and one on the outflow, as they tend to slot into the primitives we synthesize to.

module ShiftReg #(T, int LATENCY) {
    interface ShiftReg : T din'0 -> T dout'LATENCY
}

FIFO #(T, int DEPTH, int MAY_PUSH_LATENCY)

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

FWFT #(T, int DEPTH, int MAY_PUSH_LATENCY)

module FWFT #(T, int DEPTH, int MAY_PUSH_LATENCY) {
    clock clk
    action rst
    output bool may_push'-MAY_PUSH_LATENCY
    action push'0 : T push_data'0
    trigger pop_available'0 : T pop_data'0
    action pop'0
}