Hello,

My main use of Nim is for writing code that compiles to something that's 
compatible with SystemVerilog DPI-C interface.

SystemVerilog is an HDL/HVL language that can talk to C via its DPI-C 
interface. SystemVerilog compilers ship with an svdpi.h like looks like 
[this](https://github.com/kaushalmodi/nim-svdpi/blob/master/includes/svdpi.h).

For a while, I have been successfully using Nim with SystemVerilog, but today I 
stumbled across this one API function from `svdpi.h` that's showing strange 
results. Here's the function stub:
    
    
    /* Gets the fully qualified name of a scope handle */
    XXTERN const char* svGetNameFromScope(const svScope);
    
    
    Run

I am not very familiar with C, so I need help how that `const char*` return 
type should map to the Nim mapped proc.

Using `nimterop`, that function maps to this in Nim:
    
    
    proc svGetNameFromScope*(a1: svScope): cstring {.importc, cdecl, 
impsvdpiHdr.}
    
    
    Run

While everything compiles and runs, I am seeing some strange results which I 
believe could be attributed to that `const char*` return type not being mapped 
correctly.

\---

So here's the Nim code:
    
    
    import std/[strformat]
    import svdpi
    
    proc f_scopetest_sv() {.importc.}
    
    proc switchToScope(newScope: svScope) =
      let
        prevScope = svSetScope(newScope)
      echo &"f_scopetest_nim: Switched from {svGetNameFromScope(prevScope)} to 
{svGetNameFromScope(newScope)}"
      f_scopetest_sv()
    
    proc f_scopetest_nim() {.exportc, dynlib.} =
      var
        scope = svGetScope()
      let
        origScopeName = svGetNameFromScope(scope)
      
      switchToScope(scope)
      echo &"origScopeName = {origScopeName}"
      
      # Switch to the other_module scope
      scope = svGetScopeFromName("top.u_other_module".cstring)
      switchToScope(scope)
      echo &"origScopeName = {origScopeName}"
      
      # Go back to the original scope
      scope = svGetScopeFromName(origScopeName)
      switchToScope(scope)
      echo &"origScopeName = {origScopeName}"
    
    
    Run

  * When I have the `echo &"f_scopetest_nim: Switched from 
{svGetNameFromScope(prevScope)} to {svGetNameFromScope(newScope)}"` line 
commented out, everything works as expected.
  * But when I uncomment that line (that line has 2 calls to 
`svGetNameFromScope`, I see the immutable `origScopeName` mutate!!



Here's an output from a Nim/SystemVerilog co-simulation, that shows the 
`origScopeName` value changing.
    
    
    xcelium> run
    f_scopetest_nim: Switched from top to top
    In top.f_scopetest_sv
    
    origScopeName = top
    f_scopetest_nim: Switched from top to top.u_other_module
    In top.u_other_module.f_scopetest_sv
    
    origScopeName = top.u_other_module
    f_scopetest_nim: Switched from top.u_other_module to top.u_other_module
    In top.u_other_module.f_scopetest_sv
    
    origScopeName = top.u_other_module
    
    
    Run

[Source](https://github.com/kaushalmodi/nim-systemverilog-dpic/blob/d61111a9ff1b68ddb3d9c3812cb34ad02ddfbd68/fast_river_of_data_dvcon_2021/b.set_get_scope/libdpi.nim)

\---

**Summary** :

  * What is the correct way to map `const char* svGetNameFromScope(const 
svScope);` from a C header to Nim?
  * Is the above issue related to that? If not, can someone help debug this? 
For more debug data, I have the Nim-compiled C files from `.nimcache` for both 
cases (that echo statement commented and uncommented) 
[here](https://github.com/kaushalmodi/nim-systemverilog-dpic/tree/d61111a9ff1b68ddb3d9c3812cb34ad02ddfbd68/fast_river_of_data_dvcon_2021/b.set_get_scope/debug).



Thanks! 

Reply via email to