Чтение массива рег с помощью Verilator и VPI - PullRequest
1 голос
/ 19 февраля 2020

Таким образом, у меня есть следующий регистр, определенный в моем verilog

reg [31:0] register_mem [0:15]/* verilator public */;

Моя цель - из моего кода verilator c ++ прочитать каждое из 16 значений, хранящихся в нем.

Я нашел что документацию для этого материала VPI довольно сложно найти. Я до сих пор не могу понять, что такое t_vpi_vecval и каковы его параметры или если это даже правильный подход.

Вот мой подход к чтению 5-го значения в регистре

unsigned int read_regs() {
    const std::string path = "TOP.TOP.cpu.reg_file.register_mem";
    vpiHandle vh1 = vpi_handle_by_name((PLI_BYTE8*)path.c_str(), NULL);
    if (!vh1) { 
        printf("Name %s", path.c_str());
        vl_fatal(__FILE__, __LINE__, "sim_main", "No handle found: ");
    }
    const char* name = vpi_get_str(vpiName, vh1);


    s_vpi_value v;
    v.format = vpiVectorVal;
    vpi_get_value(vh1, &v);
    return v.value.vector[4].aval;
}

Независимо от того, что я здесь делаю, метод возвращает 0, предполагая, что я не смотрю на массив register_mem.

Что я делаю не так?

1 Ответ

1 голос
/ 20 февраля 2020

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

Фактически дескриптор, который вы получаете для массива, является дескриптором типа vpiRegArray. Он может быть повторен для доступа к каждому отдельному элементу.

Вот простой код, который выполняет итерацию и печатает значения каждого элемента в массиве:


#include "vpi_user.h"

PLI_INT32 preg_calltf( char *txt ) {
    vpiHandle hreg = vpi_handle_by_name("rarr.register_mem", 0);
    vpi_printf("reg type: %s\n", vpi_get_str(vpiType, hreg)); // vpiRegArray

    s_vpi_value val = {vpiDecStrVal}; // struct t_vpi_value

    vpiHandle arrayIterator = vpi_iterate( vpiReg, hreg); 
    if( arrayIterator != NULL ) {
        vpiHandle item = NULL;
        while( NULL != ( item = vpi_scan( arrayIterator ) ) ) {
            vpi_get_value(item, &val);
            vpi_printf("item type: %s = %s\n", vpi_get_str(vpiType, item), val.value.str); // vpiReg
            vpi_free_object( item );
        }
    }

    return 0;
}

В этом случае я инициализировал val с vpiDecStrVal. Он указывает компилятору подготовить результаты значений в виде десятичной строки. Значение теперь доступно как val.value.str. У вас есть несколько вариантов получения строковых или двоичных данных в представлении с 2 состояниями или 4 состояниями.

Для значений в 2 состояниях до 32 бит можно использовать целочисленное форматирование. Однако для более длинных значений или 4-х состояний вам нужно vpiVectorVal. Он фактически запрашивает verilog создать 2 массива 32-битных целых чисел, aval и bval. Оба имеют достаточно большие размеры, чтобы сохранить все биты значения. Комбинация битов в aval и bval представляет значение 4-х состояний всех битов в векторе.

Вся информация о vpi доступна в LRM, включая диаграммы отношений и структуры данных. Есть также несколько книг, например, «Справочник verilog pli» Сазерленда.

...