VPI allows to add and overwrite System Tasks and Functions. I propose to add the infrastructure to allow for that in the following way:
- Add command line switch (e.g., --vpi-systemtf) to enable this functionality
- Let Verilator not emit implementation of the systemtf, but instead emit some kind of function table with pointers to the configured implementation, along with defaults and unresolved systemtf if needed. Furthermore emit calls into the runtime that implements this.
- Implement the VPI part by accessing this function table infrastructure
- Runtime functions that implement the calls
Enabling this feature has a negative impact on performance, that's why it should definitely be optional.
I gave a very rough estimate in hours, happy to pick it up once I find time.
#1 Updated by Wilson Snyder 3 months ago
- Status changed from New to Feature
Note Verilator does support a language extension where arbitrary doller-user functions can instead be converted into DPI functions.
This suggests a refinement of what you suggest, namely Verilator would spit out automatically code that converted DPI calls into old-school VPI calls.
Another complication is verilator must know the data types of the user's functions. This is usually done by the simulator at verilation time needing to call into the user VPI routines/tables. This will be a pain.
Having these VPI extensions would be a fine addition, but I wonder if this is really in the service of users runtime wise? Could cocotb switch to generating DPI functions? This is more modern, far cleaner, and would speed up cocotb not just with Verilator but with every simulator.
#2 Updated by Stefan Wallentowitz 3 months ago
It is actually even worse: It only uses the systemtf to re-direct $display-style system functions to its output.
As you say, undergoing the full exercise seems like a massive task just for this minor part of the complexity. But I cannot come up with an acceptable workaround for that so far. I think currently, the existing implementations all just turn the Unimplemented error of registering systemtf into an empty function..
#4 Updated by Wilson Snyder 3 months ago
Adding a way to overload $display would be ok but you'd have a larger problem that display takes arguments and the DPI doesn't support vaargs. Plus then you'd need $write, etc, etc.
Knowing it's just display helps enormously. I suggest using VPI was just a hack to get around that other simulators didn't have what was really wanted, namely an output-stream override. And Verilator has better alternative paths.
1. Simplest is just -DVL_PRINTF=my_printf at compile time, all output go to a new function. You're done. Does this work?
2. See t_dpi_display.v. This defines a DPI function with printf style format. Then add a new way to override $display instead of the new name (as you suggested). This is better than VPI as Verilator understands this takes the %formats and compresses it all to a single pass-a-string call.
3. Add a new attribute that specifies a DPI function that replaces the downstream VL_PRINTF with a DPI function taking a string.
#6 Updated by Stefan Wallentowitz 1 day ago
sorry, took much longer as I hoped to even look into it. Attached please find a first, rather trivial patch, that allows us to define vpi_register_systf in our Verilator-specific cocotb infrastructure and thereby have no impact on the common code. A change there would also not be overly complex, but I would like to get your comment on whether this can be accepted from your point of view. I see no negative implications, and it is probably the only strange workaround (which is great :)
#7 Updated by Wilson Snyder 1 day ago
Weak seems somewhat hacky, but I can live with hacky. You do however need to do not break non-GCC compilers e.g. MSVCC. Please use e.g. PLI_DLLWEAK then declare that similar to how PLI_DLLISPEC is made.
A search turned up this MSVC++ somewhat equivalent to weak: https://stackoverflow.com/questions/2290587/gcc-style-weak-linking-in-visual-studio
however it might be safer just to set it to empty for MSVCC (the conditions similar to those that test to make PLL_DLLESPEC.
#8 Updated by Stefan Wallentowitz 1 day ago
Thanks, Wilson, I was already thinking about the issue with other compilers but only came up with LLVM :) I think it is easier to handle this minor issue on the cocotb side, because it is cleaner there (define out the call for Verilator).
Time to get to the actual stuff then, so please keep the issue open, thanks!
#9 Updated by Stefan Wallentowitz about 19 hours ago
Okay, here is one that is equally hacky and elegant on both sides. Instead of making the symbol weak, how about just not error'ing on unimplemented functions. The application may choose to deliberately not have it error out, then use common code to probe for existence, as per the patch attached. An improvement would be to only do it for ones that allow probing (need to check), but register_systf allows it by returning 0. But ultimately, the application developer is fully aware of this and can track on its own because otherwise they wouldn't have set -DVL_SUPPRESS_UNIMP during the compilation of the runtime. Seems like a simple "compromise" in terms of hackiness on both sides.
We can still fallback on the cocotb-side solution which requires larger #ifdef VERILATOR areas in the common code which is considered unfavored (but acceptable).
#11 Updated by Stefan Wallentowitz about 17 hours ago
Wilson Snyder wrote:
Perhaps when suppressed this should be setting the error return code so vpi_chk_error returns something sane e.g. level=vpiInternal message=Unsupported...?
Awesome, thanks! Always new sections in the LRM to learn about :) Will get onto that over the weekend!
Also available in: Atom