简体   繁体   中英

Declare a SystemVerilog variable with type depending on a parameter

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.

PS 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;

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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM