SystemVerilog中如何在generate块遍历结构体成员生成代码?
在SystemVerilog中遍历参数化结构体的命名成员
要实现遍历参数化结构体t的命名成员(而非单个比特)的需求,在SystemVerilog 2012及后续标准中,可以借助原生的$members函数结合generate块完成,这是最通用且自动化的方案。
实现示例
typedef struct packed { bit a; bit[7:0] b; bit[15:0] c; } my_struct; module x #( parameter type t = my_struct ); // 获取参数化结构体的所有成员名称数组 localparam string members[] = $members(t); generate // 遍历每个成员名称 for (int i = 0; i < members.size(); i++) begin : member_iteration string member_name = members[i]; // 示例1:打印成员信息 initial begin $display("成员名称: %s, 位宽: %0d", member_name, $bits(t::member_name)); end // 示例2:根据成员生成硬件结构(比如生成对应位宽的寄存器) reg [$bits(t::member_name)-1:0] member_reg; end endgenerate endmodule
关键说明
$members(t)函数会返回参数化类型t的所有命名成员的字符串数组,顺序与结构体定义时的顺序完全一致- 通过
t::member_name可以访问对应成员的类型信息,配合$bits()函数能获取成员的位宽,用于适配生成的硬件逻辑 - 主流EDA工具(如VCS、Questa、Xcelium)均支持该特性,需确保编译器开启SystemVerilog 2012及以上标准的支持
兼容旧版本编译器的替代方案
如果使用的编译器不支持$members函数,可以手动传递成员名称和位宽参数,虽然灵活性稍差,但能实现相同逻辑:
module x #( parameter type t = my_struct, parameter string MEMBERS[] = '{"a", "b", "c"}, parameter int MEMBER_SIZES[] = '{1, 8, 16} ); generate for (int i = 0; i < MEMBERS.size(); i++) begin : member_loop // 根据MEMBERS[i]和MEMBER_SIZES[i]生成代码 reg [MEMBER_SIZES[i]-1:0] member_reg; end endgenerate endmodule
内容的提问来源于stack exchange,提问作者Guilty
相关产品推荐
相关产品推荐

