在生成块中定义类型并在外部使用它

Define type in generate block and use it outside

我正在尝试在生成块中定义用户定义的类型,然后在生成块之外的范围内访问它。像这样:

generate
    if (SOME_PARAM == 0) begin
        typedef struct packed {
            logic [A-1:0][B-1:0] field1;
            logic [C-1:0] field2;
        } struct_id_t;
    end
    else begin
        typedef struct packed {
            logic [SOME_PARAM-1:0] other_field;
            logic [A-1:0][B-1:0] field1;
            logic [C-1:0] field2;
        } struct_id_t;
    end
endgenerate
struct_id_t some_struct_instance;

最后一行代码触发错误,指出 struct_id_t 未定义。显然,生成块创建了一个本地范围,这将解释错误。

还有其他方法吗?

在讨论我的 considered/tried 之前,我首先要说的是,我理解对此的一种解决方案是将 struct_id_t 的所有使用放在由生成块创建的本地范围内。但是,这需要在我真正希望避免的块之间重复相当多的代码。

我考虑过的其他事项:

编译器指令不会像生成块那样创建局部作用域。不幸的是,(System)Verilog 没有 ifeq 编译器指令,所以我认为这行不通。

我也试过转发声明类型。类似于:

typedef struct struct_id_t;
generate
    if (SOME_PARAM == 0) begin
        typedef struct packed {
            logic [A-1:0][B-1:0] field1;
            logic [C-1:0] field2;
        } struct_id_t;
    end
    else begin
        typedef struct packed {
            logic [SOME_PARAM-1:0] other_field;
            logic [A-1:0][B-1:0] field1;
            logic [C-1:0] field2;
        } struct_id_t;
    end
endgenerate
struct_id_t some_struct_instance;

由此产生的错误抱怨 struct_id_t 从未被定义。 1800-2012标准第6.18节错误解释:

The actual data type definition of a forward typedef declaration shall be resolved within the same local scope or generate block.

因此,定义需要在同一范围内。

我试图为包含参数定义的生成块创建标签。这样我相信我可以分层访问类型。类似于 gen_name[SOME_PARAM].struct_id_t 的内容。但这似乎不是生成块的有效名称。

我有哪些选择?

无法以这种方式在生成块中声明类型。但是,您可以在块内定义一个变量,如下所示,并将其与结构名称一起使用:

 if (SOME_PARAM == 0) begin: def
        typedef struct packed {
            logic [A-1:0][B-1:0] field1;
            logic [C-1:0] field2;
        } struct_id_t;
    struct_id_t some_struct_instance;
    end
    else begin: def
        typedef struct packed {
            logic [SOME_PARAM-1:0] other_field;
            logic [A-1:0][B-1:0] field1;
            logic [C-1:0] field2;
        } struct_id_t;
      struct_id_t some_struct_instance;
    end

assign def.some_struct_instance = 1;

另一种方法是将类型传递给 module (mod) 的实例:

module top#(SOME_PARAM = 0, A=1, B=1, C=1)();
  typedef struct packed {
    logic [A-1:0][B-1:0] field1;
    logic [C-1:0] field2;
  } struct1_id_t;
  
  typedef struct packed {
    logic [SOME_PARAM-1:0] other_field;
    logic [A-1:0][B-1:0] field1;
    logic [C-1:0] field2;
  } struct2_d_t;

  mod #(.stuct_id_t(struct1_id_t)) mod1();
  mod #(.stuct_id_t(struct1_id_t)) mod2();
endmodule

module mod#(type struct_id_t = logic) ();
  struct_id_t some_struct_instance;
    // ...
endmodule