Skip to content

Commit

Permalink
vhpi: Add support for getting record types by name
Browse files Browse the repository at this point in the history
When cocotb tries to access an object with a name like `VHPI5.O.F`, it
doesn't know whether O is a signal or a record. This ambiguity could be
resolved by trying to look up the name like `:VHPI5:O.F` or
`:VHPI5:O:F`, but cocotb can't determine which to use ahead of time.
This is a limitation of cocotb, but probably not one which will ever get
resolved.

Add support for looking up record types by name, primarily to allow
cocotb to access them.
  • Loading branch information
Forty-Bot committed Jun 22, 2023
1 parent 683a4b6 commit 9894099
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 11 deletions.
34 changes: 30 additions & 4 deletions src/vhpi/vhpi-model.c
Original file line number Diff line number Diff line change
Expand Up @@ -1589,22 +1589,48 @@ vhpiHandleT vhpi_handle_by_name(const char *name, vhpiHandleT scope)
if (elem == NULL)
return handle_for(&(region->object));

c_abstractDecl *d;
for (int i = 0; i < region->decls.count; i++) {
c_abstractDecl *d = cast_abstractDecl(region->decls.items[i]);
d = cast_abstractDecl(region->decls.items[i]);
if (strcasecmp((char *)d->Name, elem) == 0)
return handle_for(&(d->object));
goto found_decl;
}

c_rootInst *rootInst;
if ((rootInst = is_rootInst(&(region->object)))) {
for (int i = 0; i < rootInst->ports.count; i++) {
c_abstractDecl *d = cast_abstractDecl(rootInst->ports.items[i]);
d = cast_abstractDecl(rootInst->ports.items[i]);
if (strcasecmp((char *)d->Name, elem) == 0)
return handle_for(&(d->object));
goto found_decl;
}
}

return NULL;

found_decl:

char *suffix;
c_vhpiObject *obj = &(d->object);
while ((suffix = strtok_r(NULL, ".", &saveptr)) != NULL) {
c_iterator it = { };
if (!init_iterator(&it, vhpiSelectedNames, &(d->object)))
return NULL;

for (int i = 0; i < it.list->count; i++) {
c_selectedName *sn = is_selectedName(it.list->items[i]);
assert(sn != NULL);

obj = &(sn->prefixedName.name.expr.object);
if (strcasecmp((char *)sn->Suffix->decl.Name, suffix) == 0)
goto found_suffix;
}

return NULL;

found_suffix: ;
}

return handle_for(obj);
}

DLLEXPORT
Expand Down
17 changes: 10 additions & 7 deletions test/vhpi/vhpi5.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include <stdio.h>
#include <assert.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>

Expand Down Expand Up @@ -56,7 +57,7 @@ static void last_delta(const vhpiCbDataT *cb_data)
delta_recursive(o, 0, 4096);
}

void start_recursive(vhpiHandleT parent, int base, int scale)
void start_recursive(vhpiHandleT parent, int base, int scale, bool by_name)
{
int i = 0;
char name[64];
Expand All @@ -74,8 +75,10 @@ void start_recursive(vhpiHandleT parent, int base, int scale)
snprintf(name, sizeof(name), "%s.%s", parent_name,
vhpi_get_str(vhpiNameP, suffix));
fail_if(strcmp(name, (char *)vhpi_get_str(vhpiNameP, child)));
if (by_name)
fail_unless(vhpi_handle_by_name(name, NULL) == child);

start_recursive(child, base + i * scale, scale / 16);
start_recursive(child, base + i * scale, scale / 16, by_name);
}

children = vhpi_iterator(vhpiIndexedNames, parent);
Expand All @@ -84,9 +87,9 @@ void start_recursive(vhpiHandleT parent, int base, int scale)
child = vhpi_scan(children), i++) {
if (parent == n)
start_recursive(child, base + i / 5 * scale + i % 5 * scale / 16,
scale / 256);
scale / 256, false);
else
start_recursive(child, base + i * scale, scale / 16);
start_recursive(child, base + i * scale, scale / 16, false);
}

if (!i) {
Expand All @@ -107,9 +110,9 @@ void start_recursive(vhpiHandleT parent, int base, int scale)

static void start_of_sim(const vhpiCbDataT *cb_data)
{
start_recursive(m, 0, 16);
start_recursive(n, 0, 4096);
start_recursive(o, 0, 4096);
start_recursive(m, 0, 16, true);
start_recursive(n, 0, 4096, true);
start_recursive(o, 0, 4096, true);
}

void vhpi5_startup(void)
Expand Down

0 comments on commit 9894099

Please sign in to comment.