In SystemVerilog, we can use our own user-defined data structure, as the example below:
typedef struct packed {
logic [riscv::VLEN-1:0] pc;
logic [TRANS_ID_BITS-1:0] trans_id;
fu_t fu;
fu_op op;
logic [REG_ADDR_SIZE-1:0] rs1;
logic [REG_ADDR_SIZE-1:0] rs2;
logic [REG_ADDR_SIZE-1:0] rd;
riscv::xlen_t result;
logic valid;
logic use_imm;
logic use_zimm;
logic use_pc;
exception_t ex;
branchpredict_sbe_t bp;
logic is_compressed;
} scoreboard_entry_t;
For now, we don't need to know what exactly these members represent. What we can see is a user-defined data strucuture in SystemVerilog. And later we instantiate this struct as an input port in a module:
input scoreboard_entry_t issue_instr_i/*verilator public_flat_rd*/,
As you see, issue_instr_i
is of this data struct and it is exposed to verilator. When I try to access it via VPI:
vpiHandle issue_instr =vpi_handle_by_name((PLI_BYTE8*)"TOP.core.issue_instr_i", NULL);
s_vpi_value v1;
v1.format = vpiHexStrVal;
vpi_get_value(issue_instr, &v1);
printf("instruction: %s\n", v1.value.str);
Apparently it only gives me a long string of hexadecimal values.
Could anyone let me know how to access a specific member in this struct? I tried setting the VPI handle as issue_instr_i.rs1
etc, nothing worked.
For packed struct, if you know bit sizes of its members, you can use 'vpiBinStrVal' to get a binary string. You can use returned bits to segment them, according to the size of your struct. For example for the following struct
struct packed {
logic [3:0]a;
logic [1:0]b;
} v;
it might return 101011
where first 4 bits (1010) belong to a
and the last two (11) belong to b
. With unpacked structs it will not work though.
However, you should be able to access struct elements by names (if it is implemented in verilator). In vcs the following works ok:
void testme() {
vpiHandle stAll = vpi_handle_by_name("top.sram.v", 0);
s_vpi_value v1;
v1.format = vpiBinStrVal;
vpi_get_value(stAll, &v1);
vpi_printf("struct: %s\n", v1.value.str);
vpiHandle va = vpi_handle_by_name("top.sram.v.a", 0);
vpi_get_value(va, &v1);
vpi_printf("struct.a: %s\n", v1.value.str);
vpiHandle vb = vpi_handle_by_name("top.sram.v.b", 0);
vpi_get_value(vb, &v1);
vpi_printf("struct.b: %s\n", v1.value.str);
}