Reputation: 21
I want to write reusable SystemVerilog code so I need to have in module one variable with type, depending on a parameter (not different bus WIDTH, but different structs). Maybe it is possible to have one parametrized structure or to have different structures but in this case how to declare variable selecting needed struct as a type. Different structs could be declared in generte-if blocks, but they will be local to it blocks, so outside can't to get them. Maybe type conversion might help somehow.
P. S. Interfaces are not allowed to use as well as defines (macros are allowed).
Code example, I want to achieve:
typedef struct packed
{
logic a;
logic b;
} str_s;
typedef struct packed
{
logic a;
logic b;
logic c;
} str_s_with_c;
// A is a parameter
generate
if (A == "ON")
str_s_with_c array;
if (A == "OFF")
str_s array;
endgenerate
assign array.a = 1'b1;
logic t;
assign t = array.a;
or
generate
if (A == "ON")
begin
typedef struct packed
{
logic a;
logic b;
} str_s;
end
if (A == "OFF")
begin
typedef struct packed
{
logic a;
logic b;
logic c;
} str_s;
end
endhenerate
str_s array;
array.a = 1.b1;
Upvotes: 0
Views: 4793
Reputation: 12384
A usual way of doing it is to pass struct as a parameter type to the module instance.
module inst#(type struct_t=int)();
struct_t v;
endmodule
typedef struct packed
{
logic a;
logic b;
} str_s;
typedef struct packed
{
logic a;
logic b;
logic c;
} str_s_with_c;
module top;
inst #(.struct_t(str_s)) inst1();
inst #(.struct_t(str_s_with_c)) inst2();
endmodule
Answering the comment below for a single instance. In this case you can use a generate
block, instantiating the module conditionally:
module top #(ON=1)
typedef struct packed
{
logic a;
logic b;
} str_s;
typedef struct packed
{
logic a;
logic b;
logic c;
} str_s_with_c;
if (ON == 1) begin: ON1
inst #(.struct_t(str_s)) inst1();
end
else begin: ON0
inst #(.struct_t(str_s_with_c)) inst2();
end
endmodule
One caveat. You'd better declare the structs outside of the generate statements. LRM does not prevent you from declaring them inside, but this feature is not implemented in at least some of the compilers.
Upvotes: 2
Reputation: 42748
You can declare variables local to generate blocks and access them with a block name.
typedef struct packed
{
logic a;
logic b;
} str_s;
typedef struct packed
{
logic a;
logic b;
logic c;
} str_s_with_c;
// A is a parameter
if (A == "ON") begin : bname
str_s_with_c array;
end
else if (A == "OFF") begin : bname
str_s array;
end
assign bname.array.a = 1'b1;
logic t;
assign t = bname.array.a;
Note that if you want to access array.c
, that will have to be guarded with a generate-if as well.
if (A == "ON") begin
always @(posedge clk)
x = bname.array.c;
end
else if (A == "OFF") begin
always @(posedge clk)
x = something_else;
end
Upvotes: 1