Verilog 如何通过索引访问压缩结构中的元素?

Verilog 如何通过索引访问压缩结构中的元素?,verilog,system-verilog,register-transfer-level,Verilog,System Verilog,Register Transfer Level,我有以下结构: typedef struct packed { type1_t info1; type2_t info2; } module_info_registers_t; typedef struct packed { logic [0:0] data1; logic [2:0] data2; logic [11:0] data3; logic [15:0] data4; } info1; typedef struct p

我有以下结构:

typedef struct packed {
    type1_t  info1;
    type2_t  info2;
} module_info_registers_t;

typedef struct packed {
    logic  [0:0] data1;
    logic  [2:0] data2;
    logic [11:0] data3;  
    logic [15:0] data4;  
} info1;

typedef struct packed {
    logic  [1:0] data1;
    logic  [3:0] data2;
    logic [10:0] data3;  
    logic [14:0] data4;  
} info2;
如您所见,type1_t和type2_t被定义为32位数据结构

我想举例说明以下内容:

module_info_registers_t myregs;
我希望根据索引访问寄存器(而不是必须键入myreqs.info2.data4):

这是因为module\u info\u registers\t的定义会不时更改,并且是自动生成的,所以我不想在RTL中硬编码'info2'

然而,我得到一个错误,说我不能对标量对象进行切片


我明白,由于某些原因,我无法以我想要的方式访问数据。有没有其他方法可以实现我想要实现的目标?

在verilog中没有任何方法可以实现您想要的目标。您可以使用宏或对结构字段的位级访问

宏可以这样做:

`define ACCESS_REG(R, NUM) R.info``NUM
module_info_registers_t regs;
`ACCESS_REG(regs, 1).data1 = 0;
假设对字段应用了某些命名约定,上述方法将起作用

使用位级访问,您需要能够计算每个结构成员的偏移量和宽度,从而使声明和使用更加复杂。以下是一个非常简化的系统Verilog示例,以便于说明:

typedef struct packed {
  logic [1:0] f1;
  logic [2:0] f2;
  logic [3:0] f3;
} sp_t;

sp_t sp;
sp[$bits(sp.f3) + $bits(sp.f2)  +: $bits(sp.f3)] = 2'b10;
上述示例将设置“sp.f1”

因此,在您的例子中,您可以创建描述相应字段的偏移量和宽度的参数数组,并将它们用于索引。所以,在你的情况下,类似的方法可能会奏效:

parameter int info[2] = {0, 32};
parameter int data1Offset[2] = {31, 30};
parameter int data1Width[2] = {1, 2};

module_info_registers_t regs;
regs[info[1] + data1Offset[1] +: data1Width[1]] = 0;

我会将所有成员迭代到一个列表中,然后您可以通过索引进行访问。@EJD,这是用于verilog的。你的答案仍然适用吗?谢谢,我对verilog一无所知,更重要的是为您指明了方向。如果名称(
info2
)将改变,那么该特定寄存器的索引(
[1]
)也会改变吗?理想情况下,您的寄存器的名称不会改变,您可以始终将寄存器称为
info2
@Unn,是的,数据会改变。我有一个FSM,它将数据从一些寄存器发送到另一个模块。它会对所有寄存器执行此操作,但在写入RTL时,寄存器的总数未知,但上界是已知的,以便适当设置索引位宽度。对于该结构中的大量32位数据结构,代码需要灵活。
parameter int info[2] = {0, 32};
parameter int data1Offset[2] = {31, 30};
parameter int data1Width[2] = {1, 2};

module_info_registers_t regs;
regs[info[1] + data1Offset[1] +: data1Width[1]] = 0;