VHDL record to Systemverilog struct

I have been reading a few papers and the questa manual for data type mapping between VHDL and systemverilog.

Currently i am wanting to map a custom VHDL record into systemverilog interface. I have created a systemverilog struct with the same elements as the vhdl record and i have instantiated this struct in the interface.

The connection at the top level is as normal, however i end up with a questa errror



** Fatal: (vsim-3362) The type of VHDL port 'reg_fld_out' is invalid for Verilog connection (35th connection).
#    Time: 0 ps  Iteration: 0  Instance: /top/dut_wrapper File: /top/block_A_dut_wrapper.vhd Line: 97


Verror states



Message # 3362:
The type of VHDL port is either not compatible with the type of Verilog
connection or is not currently supported at the VHDL-SystemVerilog mixed
language boundary. Please refer to QuestaSim User's Manual for a list of
supported types.

I have compiled the vhdl with -mixedsvh option, and my struct and record content types match. Does anyone have any ideas on why this isn’t working for me?

Thanks

The purpose of using the ‘-mixedsvvh’ option is to generate a SystemVerilog package that is equivalent to the VHDL package so you don’t have to worry about creating your own SV package and trying to map the data types correctly.

Have you tried importing the VHDL package name in your SV code? The use mode varies somewhat based on what you are trying to accomplish, but Questasim provides some examples for this.

In reply to cgales:

I have a separate compile process for the vhdl and the systemverilog. The vhdl is compiled into a different library and vmapped before vsim.
So if i import the vhdl package, the compiler will complain because it has no visibility of its contents.

Can i forward declare the package? I have seen this down with classes and types, but not packages.

I have not seen any questa examples - do you have a specific one in mind?

Thanks

In reply to Phill_Ferg:

You cannot forward declare packages - a fundamental principle of a package (VHDL or SystemVerilog) is that it must be compiled before it can be referenced.

You can compile your VHDL first, and then reference the library it was compiled into using the vlog -L switch.

See /examples/mixedlang/mixed_package_sharing

In reply to dave_59:

I have seen the examples and it does seem very trivial. They are both compiled into the same work lib, but the vlog -L flag gets around this.
So i am still a little puzzled that i still have errors here.

Just to confirm my vcom and vlog commands and the resultant error.

vcom -32 -2002 -l design.log -work design +cover=bcesft -novopt -mixedsvvh -f /home/user7/design.f

vlog -32 -work work -timescale 1ns/1ps -writetoplevels questa.tops +incdir+/APPS/questasim/10.3a/questasim/verilog_src/uvm-1.1d/src -mfcu -incr +acc=varg -L design -f /home/user7/testbench.f

I have imported the vhdl package into my interface, but i am still unable to use the VHDL record types. The vlog compilation error is still related to visibility.

** Error: ** while parsing file included at …/tb/top/registerHW_if/registerHW_pkg.sv(19)
** at …/tb/top/registerHW_if/registerHW_if.sv(49): (vlog-2143) Unable to find ‘register_outputs’ in scope registerHW_if.
** Error: ** while parsing file included at …/tb/top/registerHW_if/registerHW_pkg.sv(19)
** at …/tb/top/registerHW_if/registerHW_if.sv(50): (vlog-2143) Unable to find ‘register_inputs’ in scope registerHW_if.

In reply to Phill_Ferg:

This is my debug flow, so for the time being, the DUT will always be compiled without an optimization step. I also use questas run manager, where optimization is enabled. This hopefully addresses the +acc option as well. The vopt in the run manager scripts have both these options.

Since i am passing file lists to vlog, i assumed i needed -mfcu? However i guess if i am not spreading declarations across different files i probably dont need this?

How will questa know what version of UVM to use if i don’t tell it?

I have shortened the code to be concise

library ieee;
use ieee.std_logic_1164.all;

package pkg_cpu_pcie is

   type reg_fld_outT is record
      R8_PROCESSING_CNTRL_REG_r        :  std_logic                    ;
      R7_PROCESSING_CNTRL_REG_r        :  std_logic                    ;
      R6_PROCESSING_CNTRL_REG_r        :  std_logic                    ;
      R5_PROCESSING_CNTRL_REG_r        :  std_logic                    ;
      R4_PROCESSING_CNTRL_REG_r        :  std_logic                    ;
      R3_PROCESSING_CNTRL_REG_r        :  std_logic                    ;
      R2_PROCESSING_CNTRL_REG_r        :  std_logic                    ;
      R1_PROCESSING_CNTRL_REG_r        :  std_logic                    ;
      FP_PROCESSING_CONFIG_REG_r       :  std_logic_vector(15 downto 0);
      ITC_PROCESSING_CONFIG_REG_r      :  std_logic_vector(2 downto 0) ;
      ITB_PROCESSING_CONFIG_REG_r      :  std_logic_vector(2 downto 0) ;
      ITA_PROCESSING_CONFIG_REG_r      :  std_logic_vector(2 downto 0) ;
      FI_FW_VERSION_REG_r              :  std_logic_vector(14 downto 0);
      FV_FW_VERSION_REG_r              :  std_logic_vector(16 downto 0);
   end record;

   type reg_fld_inT is record
      FI_FW_VERSION_REG_r_ip              :  std_logic_vector(14 downto 0);
      FV_FW_VERSION_REG_r_ip              :  std_logic_vector(16 downto 0);
      CIT_INTERNAL_TIME_REG_BASE_r_ip     :  std_logic_vector(31 downto 0);
      ITL_INTERNAL_TIME_REG_4_r_ip        :  std_logic_vector(31 downto 0);
      SC_NUC_CNTRL_REG_BASE_r_ip          :  std_logic                    ;
      SB_NUC_CNTRL_REG_BASE_r_ip          :  std_logic                    ;
      SA_NUC_CNTRL_REG_BASE_r_ip          :  std_logic                    ;
   end record;
end package pkg_cpu_pcie;

Now for some Sv code:

My interface with the record:


interface registerHW_if(input clock, input reset);
	
	import pkg_cpu_pcie::*;
	
	// Control whether checks are enabled.
	bit                has_checks = 1	;
	// Control whether coverage is enabled.
	bit                has_coverage = 1	;
  
	// clocking block parameters  
	parameter 			setup_time = 1ns	;
	parameter 			hold_time  = 1ns	;	
    
	reg_fld_inT	register_inputs		;
	reg_fld_outT	register_outputs	;	

 	clocking registerHW_cb @ (posedge clock)		;
		default input #setup_time output #hold_time	;
		input  	register_outputs			;
		output 	register_inputs				;	          
	endclocking:registerHW_cb

endinterface : registerHW_if

And the top level where i connect the same tpes:


    // register Hardware pins
    .reg_fld_in			(registerHW_interface.register_inputs),
    .reg_fld_out		(registerHW_interface.register_outputs),

In reply to Phill_Ferg:

Just to confirm the error in the above code:

When a VHDL package is used for SV, all the identifiers are converted to lower case. This is done to prevent any upper/lower case conflicts. If you change reg_field_inT and reg_field_outT to reg_field_int and reg_field_outt, everything should compile successfully.

Thanks cgales!

In reply to Phill_Ferg:

I was using Questa 10.1 and importing VHDL record without issue.

We recently moved to 10.3a and ran into some problems with this. If we use vopt +acc options-- everything is fine. If we shut off optimization with the -novopt switch, the simulator complains it cannot the *_sv_unit package file.

In reply to wpiman:

You should never use the -novopt switch.

In reply to cgales:

Then it should be removed by Modelsim.

Sort of a cop out answer…

In reply to wpiman:

This is not a tool support forum. It is to help with methodology for writing code.

I will say that mixed language simulation has some limitations when using -novopt and you will need to contact Mentor support for more information.

Dave

In reply to dave_59:

True. Mixed language support is not defined by any standard per se.