Search code examples
structsystem-verilogquestasimsystem-verilog-dpi

Systemverilog: Simulation error when passing structs as module input\outputs


I am trying to pass one structure as an input and get the output in another structure. However I am having some issues during simulation. The following example code compiles fine in questasim, however the simulation gives the following error:

Connection type 'core_tb_sv_unit.struct ' is incompatible with 'core_sv_unit.struct ' for port (struct_in): Struct/union types must match.

MyStruct.sv

`ifndef _DEF_
`define _DEF_

typedef struct {
    real instr;
    real addr;
} instr_packet_s;

`endif

core.sv

`timescale 1ns / 1ns
`include "MyStruct.sv"

module core(
    input instr_packet_s struct_in,
    output instr_packet_s struct_out

);
initial begin
     $display("Initial");
end

endmodule

core_tb.sv

`include "MyStruct.sv"

module core_tb();

instr_packet_s struct_in_tb,struct_out_tb; 

assign struct_in_tb.instr=2;
assign struct_in_tb.addr=3;


core u_core(
.struct_in(struct_in_tb),
.struct_out(struct_out_tb)
);
endmodule

What am I missing?.

I know interfaces are the suggested workflow here,but the input to the model will be passed to a C routine using DPI. The DPI interface supports structures, I do not think it supports interfaces. This is why I would like to stick to simple structures.


Solution

  • SystemVerilog has strong typing rules for user defined types. A typed declared in one scope is not the same as a type declared in another scope, even if it has the same name and same internal layout. A user defined type is only compatible with itself. Define your types in a package and import the package in each file. See http://go.mentor.com/package-import-versus-include

    By default, Questa treats each file on the vlog command line as a separate compilation unit, like C/C++. So all compiler directives (`defines) and declaration in the first file are not visible to the contents of the second file. So your typedef gets executed when compiling both the core.sv and core_tb.sv files.

    I believe incisive concatenates all the files on the command line, and then compiles the file, so there is only one compilation unit, and there is only on typedef.

    There is a way to change the Questa default, but I'm not going to tell you it because I don't recommend doing it that way. It makes things very difficult when you want to take advantage of separate compilation in larger environments.