From a7cd483247abffe581f20faaf59ec95ef8254b78 Mon Sep 17 00:00:00 2001 From: Sean Anderson Date: Sun, 2 Jul 2023 14:25:45 -0400 Subject: [PATCH] vhpi: Add support for argv Add support for reading the argvs, allowing tools to parse out plusargs. --- NEWS.md | 2 ++ src/nvc.c | 2 +- src/vhpi/vhpi-model.c | 41 ++++++++++++++++++++++++++++++++----- src/vhpi/vhpi-util.c | 5 +++-- src/vhpi/vhpi-util.h | 5 +++-- test/regress/gold/vhpi1.txt | 3 +++ test/vhpi/vhpi1.c | 11 +++++++++- 7 files changed, 58 insertions(+), 11 deletions(-) diff --git a/NEWS.md b/NEWS.md index 43eb5c28..8bab2802 100644 --- a/NEWS.md +++ b/NEWS.md @@ -9,6 +9,8 @@ `to_string` function was changed to match other simulators. - Fixed a crash when constant folding a locally static expression in a package body (#742). +- Added support for reading command line arguments in VHPI (from + @Forty-Bot). ## Version 1.10.0 - 2023-07-14 - The Zstandard compression library is now a build dependency. Install diff --git a/src/nvc.c b/src/nvc.c index 54ae072c..dad2b0a0 100644 --- a/src/nvc.c +++ b/src/nvc.c @@ -719,7 +719,7 @@ static int run(int argc, char **argv) rt_model_t *model = model_new(top, jit); if (vhpi_plugins != NULL) - vhpi_load_plugins(top, model, vhpi_plugins); + vhpi_load_plugins(top, model, vhpi_plugins, next_cmd - 1, argv + 1); set_ctrl_c_handler(ctrl_c_handler, model); diff --git a/src/vhpi/vhpi-model.c b/src/vhpi/vhpi-model.c index afaf473f..a39da125 100644 --- a/src/vhpi/vhpi-model.c +++ b/src/vhpi/vhpi-model.c @@ -44,6 +44,13 @@ typedef struct { typedef A(c_vhpiObject *) vhpiObjectListT; +typedef struct { + c_vhpiObject object; + vhpiStringT StrVal; +} c_argv; + +DEF_CLASS(argv, vhpiArgvK, object); + typedef struct { c_vhpiObject object; vhpiObjectListT argv; @@ -611,6 +618,19 @@ static vhpiCharT *new_string_n(const char *s, size_t n) return p; } +static c_tool *build_tool(int argc, char **argv) +{ + c_tool *t = new_object(sizeof(c_tool), vhpiToolK); + + for (int i = 0; i < argc; i++) { + c_argv *arg = new_object(sizeof(c_argv), vhpiArgvK); + arg->StrVal = new_string(argv[i]); + APUSH(t->argv, &(arg->object)); + } + + return t; +} + static void init_abstractRegion(c_abstractRegion *r, tree_t t) { const loc_t *loc = tree_loc(t); @@ -1768,9 +1788,12 @@ vhpiIntT vhpi_get(vhpiIntPropertyT property, vhpiHandleT handle) } case vhpiArgcP: - if (obj->kind != vhpiToolK) - vhpi_error(vhpiInternal, &(obj->loc), "vhpiArgcP is only supported for tool objects"); - return 0; + { + c_tool *t = cast_tool(obj); + if (t == NULL) + return vhpiUndefined; + return t->argv.count; + } case vhpiNumDimensionsP: { @@ -1999,6 +2022,14 @@ const vhpiCharT *vhpi_get_str(vhpiStrPropertyT property, vhpiHandleT handle) } } + c_argv *arg = is_argv(obj); + if (arg != NULL) { + switch(property) { + case vhpiStrValP: return arg->StrVal; + default: goto unsupported; + } + } + unsupported: fatal_trace("unsupported property %s in vhpi_get_str", vhpi_property_str(property)); @@ -2789,7 +2820,7 @@ static void vhpi_build_ports(tree_t unit, c_rootInst *where) } } -void vhpi_build_design_model(tree_t top, rt_model_t *m) +void vhpi_build_design_model(tree_t top, rt_model_t *m, int argc, char **argv) { const uint64_t start_us = get_timestamp_us(); @@ -2814,7 +2845,7 @@ void vhpi_build_design_model(tree_t top, rt_model_t *m) model = m; - tool = new_object(sizeof(c_tool), vhpiToolK); + tool = build_tool(argc, argv); c_entityDecl *entity = new_object(sizeof(c_entityDecl), vhpiEntityDeclK); init_entityDecl(entity, p); diff --git a/src/vhpi/vhpi-util.c b/src/vhpi/vhpi-util.c index 3875b125..f2d16b10 100644 --- a/src/vhpi/vhpi-util.c +++ b/src/vhpi/vhpi-util.c @@ -326,11 +326,12 @@ uint64_t vhpi_time_to_native(const vhpiTimeT *time) return ((uint64_t)time->high << 32) | (uint64_t)time->low; } -void vhpi_load_plugins(tree_t top, rt_model_t *model, const char *plugins) +void vhpi_load_plugins(tree_t top, rt_model_t *model, const char *plugins, + int argc, char **argv) { vhpi_clear_error(); - vhpi_build_design_model(top, model); + vhpi_build_design_model(top, model, argc, argv); char *plugins_copy LOCAL = xstrdup(plugins); diff --git a/src/vhpi/vhpi-util.h b/src/vhpi/vhpi-util.h index 8269d98a..da05418f 100644 --- a/src/vhpi/vhpi-util.h +++ b/src/vhpi/vhpi-util.h @@ -32,7 +32,7 @@ #include "vhpi/vhpi_user.h" // Simulator interface to VHPI -void vhpi_build_design_model(tree_t top, rt_model_t *m); +void vhpi_build_design_model(tree_t top, rt_model_t *m, int argc, char **argv); __attribute__((format(printf, 2, 3))) void vhpi_trace(const char *func, const char *fmt, ...); @@ -40,7 +40,8 @@ void vhpi_trace(const char *func, const char *fmt, ...); __attribute__((format(printf, 3, 4))) void vhpi_error(vhpiSeverityT sev, const loc_t *loc, const char *fmt, ...); -void vhpi_load_plugins(tree_t top, rt_model_t *model, const char *plugins); +void vhpi_load_plugins(tree_t top, rt_model_t *model, const char *plugins, + int argc, char **argv); void vhpi_clear_error(void); rt_event_t vhpi_get_rt_event(int reason); diff --git a/test/regress/gold/vhpi1.txt b/test/regress/gold/vhpi1.txt index 739c8cc4..4f9f0f5c 100644 --- a/test/regress/gold/vhpi1.txt +++ b/test/regress/gold/vhpi1.txt @@ -2,6 +2,9 @@ loading VHPI plugin VHPI printf hello, world! VHPI printf tool is nvc VHPI printf tool version is +VHPI printf arg is -r +VHPI printf arg is --load= +VHPI printf arg is vhpi1 VHPI printf root handle VHPI printf root name is VHPI1 VHPI printf root full name is :VHPI1 diff --git a/test/vhpi/vhpi1.c b/test/vhpi/vhpi1.c index e294083b..a1f10779 100644 --- a/test/vhpi/vhpi1.c +++ b/test/vhpi/vhpi1.c @@ -339,6 +339,15 @@ void vhpi1_startup(void) fail_if(tool == NULL); vhpi_printf("tool is %s", vhpi_get_str(vhpiNameP, tool)); vhpi_printf("tool version is %s", vhpi_get_str(vhpiToolVersionP, tool)); + + vhpiHandleT args = vhpi_iterator(vhpiArgvs, tool); + fail_if(args == NULL); + int i = 0; + for (vhpiHandleT arg = vhpi_scan(args); arg != NULL; arg = vhpi_scan(args), i++) + vhpi_printf("arg is %s", vhpi_get_str(vhpiStrValP, arg)); + fail_unless(vhpi_get(vhpiArgcP, tool) == i); + fail_if(1); + vhpi_release_handle(tool); vhpiHandleT root = vhpi_handle(vhpiRootInst, NULL); @@ -354,7 +363,7 @@ void vhpi1_startup(void) vhpiHandleT root_ports = vhpi_iterator(vhpiPortDecls, root); fail_if(root_ports == NULL); - int i = 0; + i = 0; for (vhpiHandleT port = vhpi_scan(root_ports); port != NULL; port = vhpi_scan(root_ports), i++) { vhpi_printf("root port is %s", vhpi_get_str(vhpiNameP, port)); fail_unless(vhpi_handle_by_index(vhpiPortDecls, root, i) == port); -- 2.39.2