You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 21:42:54