Как получить доступ к элементам упакованной структуры по индексу?

У меня есть следующие структуры:

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):

myregs[1].data4

Это связано с тем, что определение module_info_registers_t время от времени меняется и генерируется автоматически, поэтому я не хочу жестко кодировать «info2» в своем RTL.

Однако я получаю сообщение об ошибке, говорящее о том, что у меня не может быть среза скалярного объекта.

Я понимаю, что по какой-то причине я не могу получить доступ к данным так, как хочу. Есть ли другой способ сделать то, чего я пытаюсь достичь?


person Veridian    schedule 18.03.2019    source источник
comment
stackoverflow.com/questions/7613782/ Я бы перебрал все члены в список, то вы можете получить доступ по индексу.   -  person EJD    schedule 18.03.2019
comment
@EJD, это для Verilog. Ваш ответ все еще актуален? Спасибо   -  person Veridian    schedule 18.03.2019
comment
Я ничего не знаю о verilog, это было больше, чтобы указать вам направление.   -  person EJD    schedule 18.03.2019
comment
Если имя (info2) изменится, не изменится ли индекс ([1]) для этого конкретного регистра? В идеале у вас просто должны быть имена для ваших регистров, которые не меняются, и вы всегда можете обратиться к регистру как info2   -  person Unn    schedule 18.03.2019
comment
@Unn, да, данные изменятся. У меня есть FSM, который отправляет данные из некоторых регистров в другой модуль. Он делает это для всех регистров, но общее количество регистров неизвестно при записи RTL, но известна верхняя граница, так что разрядность индекса устанавливается соответствующим образом. Код должен быть гибким для большого количества 32-битных структур данных в этой структуре.   -  person Veridian    schedule 19.03.2019


Ответы (1)


В Verilog нет возможности делать то, что вы хотите. Вы можете обойти это с помощью макросов или побитового доступа к полям структуры.

Макросы можно сделать так:

`define ACCESS_REG(R, NUM) R.info``NUM
module_info_registers_t regs;
`ACCESS_REG(regs, 1).data1 = 0;

Приведенное выше будет работать, если к полям применяются определенные соглашения об именах.

с доступом на уровне битов вы должны иметь возможность вычислять смещение и ширину каждого члена структуры, что усложняет объявление и использование. Вот очень упрощенный пример System 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;
person Serge    schedule 19.03.2019