In reply to dave_59:
Also consider using an interface type parameter instead.
interface foo_if
#(
type atom_t = bit [ 7 : 0 ]
);
//...
localparam int ATOM_DIMENSIONS = $dimensions( atom_t );
localparam int ATOM_ELEMENT_SIZE = $size( atom_t, ATOM_DIMENSIONS );
localparam int TOTAL_ELEMENTS = $bits( atom_t ) / ATOM_ELEMENT_SIZE;
atom_t my_data;
//...
endinterface
The default “atom_t” works with a single dimensional (8-bit scaler). But, the interface can support different sized scalers, as was as n-dimensional arrays (of varying types) - all controlled by the parameter type passed in from the parent interface instantiation. i.e.
module top;
typedef bit [ 2 : 0 ][ 7 : 0 ] my_pixel_t;
foo_if #( .atom_t( my_pixel_t ) ) rgb_pixel_if();
endmodule
I use these quite a lot - however for ease, I tend to require atom_t to be a packed typed. I’ve even used packed structures in the parameter type override.