在生成块中定义类型并在外部使用它
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
我正在尝试在生成块中定义用户定义的类型,然后在生成块之外的范围内访问它。像这样:
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