veryl-std 0.20.3

A modern hardware description language
Documentation
pub module ram #(
    param WORD_SIZE    : u32       = 1                                        ,
    param ADDRESS_WIDTH: u32       = if WORD_SIZE >= 2 ? $clog2(WORD_SIZE) : 1,
    param DATA_WIDTH   : u32       = 8                                        ,
    param DATA_TYPE    : type      = logic<DATA_WIDTH>                        ,
    param BUFFER_OUT   : bbool     = false                                    ,
    param USE_RESET    : bbool     = false                                    ,
    param INITIAL_VALUE: DATA_TYPE = 0 as DATA_TYPE                           ,
) (
    i_clk : input  clock                   ,
    i_rst : input  reset                   ,
    i_clr : input  logic                   ,
    i_mea : input  logic                   ,
    i_wea : input  logic                   ,
    i_adra: input  logic    <ADDRESS_WIDTH>,
    i_da  : input  DATA_TYPE               ,
    i_meb : input  logic                   ,
    i_adrb: input  logic    <ADDRESS_WIDTH>,
    o_qb  : output DATA_TYPE               ,
) {
    var ram_data: logic<$bits(DATA_TYPE)> [WORD_SIZE];
    var q       : logic<$bits(DATA_TYPE)>            ;

    if USE_RESET :g_ram {
        always_ff {
            if_reset {
                ram_data = '{default: INITIAL_VALUE};
            } else if i_clr {
                ram_data = '{default: INITIAL_VALUE};
            } else if i_mea && i_wea {
                ram_data[i_adra] = i_da;
            }
        }
    } else {
        always_ff {
            if i_mea && i_wea {
                ram_data[i_adra] = i_da;
            }
        }
    }

    always_comb {
        o_qb = q as DATA_TYPE;
    }

    if !BUFFER_OUT :g_out {
        always_comb {
            q = ram_data[i_adrb];
        }
    } else if USE_RESET {
        always_ff {
            if_reset {
                q = INITIAL_VALUE;
            } else if i_clr {
                q = INITIAL_VALUE;
            } else if i_meb {
                q = ram_data[i_adrb];
            }
        }
    } else {
        always_ff {
            if i_meb {
                q = ram_data[i_adrb];
            }
        }
    }
}