Как вы определяете бэкдор доступ для полей, которые охватывают два регистра?

У меня есть карта регистров, которая имеет 16-битные регистры. У меня есть поле с шириной более 16 бит, поэтому оно должно охватывать два адреса. Как мне определить бэкдор доступ к этому полю?

Это то, что я пытался для моей области test_pattern[23:0]:

register_a.add_hdl_path_slice("path.to.regmap.test_pattern[15:0]", 0, 16);
register_b.add_hdl_path_slice("path.to.regmap.test_pattern[23:16]", 0, 8);

Это терпит неудачу с этой ошибкой:

ОШИБКА: VPI TYPERR vpi_handle_by_name() не может получить дескриптор выбора детали.

Не ясно, является ли это ограничением моего инструмента или того, как код UVM использует VPI. После осмотра внутри кода UVM я вижу код, который должен обрабатывать выборки части, но он внутри #ifdef QUESTA директивы, так что я думаю, что это ограничение инструмента.

Есть ли хорошая работа для этого?

3 ответа

Очень жаль, что тот, кто внес этот код (предположительно, Mentor?), Счел необходимым добавить полезную функцию в библиотеку Universal, обернутую в ifdefs, На самом деле это еще хуже на UVM_1_2 ветвь, где весь файл интерфейса DPI/PLI разделен на специфические реализации симулятора!

Смотря на distrib/src/dpi/uvm_hdl.c в основной ветке git://git.code.sf.net/p/uvm/code похоже, что единственным конкретным кодом для QUESTA является эта функция:

static int uvm_hdl_set_vlog_partsel(char *path, p_vpi_vecval value, PLI_INT32 flag);
static int uvm_hdl_get_vlog_partsel(char *path, p_vpi_vecval value, PLI_INT32 flag);

Который использует следующие значения, определенные DPI:

svLogic logic_bit;
svGetBitselLogic(&bit_value,0);
svLogicVecVal bit_value;
svGetPartselLogic(&bit_value,value,i,1);
svPutPartselLogic(value,bit_value,i,1);

Теоретически, если ваш симулятор и код Mentor соответствуют стандарту, вы можете удалить ifdefs и это все еще должно работать.

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

Обратите внимание, что мой первоначальный ответ был неверным по поводу того, что код был специфичен для Mentor - спасибо @dave_59 за то, что он прямо сказал мне, и извиняюсь перед Mentor.

Согласно справке класса UVM:

функция void add_hdl_path_slice(имя строки,
    смещение int,
    размер int,
    бит первый = 0,
    string kind = "RTL")

Я предполагаю, что решение должно использовать offset выбрать начальный индекс.

register_a.add_hdl_path_slice("path.to.regmap.test_pattern", 0, 16);
register_b.add_hdl_path_slice("path.to.regmap.test_pattern", 16, 8);

Возможная альтернатива, бит выбора в цикле for:

for (int i=0; i<16; i++) begin
  string tmp_path_s;
  tmp_path_s = $sformatf("path.to.regmap.test_pattern[%0d]", i);
  register_a.add_hdl_path_slice(tmp_path_s, i, 1);
end
for (int i=0; i<8; i++) begin
  string tmp_path_s;
  tmp_path_s = $sformatf("path.to.regmap.test_pattern[%0d]", i+16);
  register_a.add_hdl_path_slice(tmp_path_s, i, 1);
end

Есть ли какая-то причина, по которой вы не делите это на 2 регистра? Поскольку размер вашего регистра равен 16 битам, нет смысла объявлять регистр, который больше этого.

То, как я видел большие поля, как это определено, состоит в том, чтобы объявить 2 регистра с отдельным полем в каждом. Например, если вам нужен 32-битный указатель, вы получите:

addr_high с 16-битным полем addr_low с 16-битным полем

Для удобства вы можете добавить задачу, которая будет обращаться к обоим по порядку.

Другие вопросы по тегам