SystemVerilog added packages to provide namespaces for common code pieces (functions, types, constants, etc). But since packages are not instantiated, they cannot be parame
I have a couple of thoughts. First, I would lean towards modeling my data using classes instead of structs. Classes can be parameterized, dynamically allocated, randomized, contain covergroups, etc. I only use structs when I want a packed struct. Packed structs are wonderful because you can assign to them like a regular vector and then access the data using the named fields. Very nice. :)
Second, even if it were possible to redefine package parameters, there is only one "instance" of a package in a simulation; there can't be multiple specializations with different parameter values like there can be for modules or classes. So it seems to me that doing away with the parameter and using a macro instead is a workable solution. Although I don't like using macros, that would allow you to recompile with new values without changing the source code.
I had the same question and a coworker suggested the following:
//defines.sv:
`ifndef MY_DEFINES
`define MY_DEFINES
`define TYPEDEF_VECTOR_T typedef logic [WIDTH-1:0] vector_t;
`endif
//mod_sub.sv:
`include "defines.sv"
module mod_sub #(parameter WIDTH = 32);
...
`TYPEDEF_VECTOR_T
vector_t some_reg;
...
endmodule
//mod_top.sv:
module mod_top;
mod_sub #(.WIDTH(8)) mod_sub8;
mod_sub #(.WIDTH(64)) mod_sub64;
endmodule
I believe System Verilog packages are elaborated before any modules thus their contents cannot be modified by parameters at compile time.
This may or may not apply, depending on exactly what you have in mind to put in the package, but interfaces can be parameterized and are synthesizable if your tool supports it.
There is an example at http://www.doulos.com/knowhow/sysverilog/tutorial/interfaces/
I wouldn't say it's a missing feature. What you're trying to do has been done with macros in Verilog for decades. Trouble is you've got to be rather unique in the way you name things to avoid clashes between packages. It's not nice, but it works.
Parameters are a bit different. They are for customising on an instance by instance basis (like VHDL generics). Either on modules for logic, or classes for test-benches. My only criticism of them is once you start using them they tend to propagate throughout your hierarchy, and the syntax isn't exactly compact. Very powerful though, and great for code re-use.
I know that this is a very old post but I have been struggling with this issue for quite some time now. I believe I have found a suitable solution but I don't currently have the toolset to verify if this can synthesize successfully.
See section 5.6.7 in: http://www.sutherland-hdl.com/papers/2013-SNUG-SV_Synthesizable-SystemVerilog_paper.pdf
By using a static parameterized class with static functions, you can call different parameterizations of each data type on the fly and keep them unique for each instantiation.
Can anyone verify that this is a viable solution? Thanks!
You could use parameterized macros to name a type with particular widths:
`define SIMPLE_STRUCT(NAME) \
simple_struct_t_``NAME``
`define SIMPLE_STRUCT_DEF(NAME, ADDR_MSB, DATA_MSB) \
typedef struct { \
logic [ADDR_MSB``:0] address; \
logic [DATA_MSB:0] data; \
} `SIMPLE_STRUCT(NAME)
Then, in some place in your code, you can define the structure(s) you need:
`SIMPLE_STRUCT_DEF(narrow, 7, 31)
`SIMPLE_STRUCT_DEF(wide, 15, 63)
And, then use it wherever you need it, using only the name:
`SIMPLE_STRUCT(narrow) narrow1, narrow2;
narrow1.data = 0;
narrow2 = narrow1;
...