llvm / circt

Circuit IR Compilers and Tools
https://circt.org
Other
1.67k stars 298 forks source link

[ExportVerilog] [SV] Open array raw data is not accessible from verilator #7465

Open uenoku opened 3 months ago

uenoku commented 3 months ago

sv:

import "DPI-C" function void dpi(input int a []); 

module DPI(
);

  wire [31:0] _GEN_0 [2:0]; // this style is currently emitted by ExportVerilog
  int _GEN_1 [2:0];

  assign _GEN_0 = '{2, 3, 4};
  assign _GEN_1 = '{2, 3, 4};

  initial begin
          dpi(_GEN_0);
          dpi(_GEN_1);
          $finish();
  end

endmodule

C++ implementation:

#include <svdpi.h>
#include <iostream>
extern "C" void dpi(const svOpenArrayHandle array) {
  // svGetArrayPtr returns non-null when the internal data representation is compatible to C.
  if (svGetArrayPtr(array)) {
    std::cout << "Have C-memory layout\n";
  }else{
    std::cout << "Doesn't have C-memory layout\n";
  }
}
$ verilator bar.sv bar.cpp --binary
$ ./obj_dir/Vbar
Doesn't have C-memory layout
Have C-memory layout
$ vcs -sverilog bar.sv bar.cpp 
$ ./simv
Have C-memory layout
Have C-memory layout

In verilator memory layout of value that corresponds to_GEN_0 doesn't have C-compatible layout whereas it has in vcs. As shown by _GEN_1, if we can emit the array as int array then it seems verilator is able to use c-compatible layout.

fabianschuiki commented 3 months ago

Out of curiosity, what happens in Verilator if we emit a variable instead of a wire?

bit [31:0] _GEN_0 [2:0];
// instead of wire [31:0] _GEN_0 [2:0];