Instantiate VHDL entity with 2D array from SystemVerilog - vhdl

There seems to be very little documentation on how to pass 2D arrays between VHDL and SystemVerilog. I have a port of the following type in VHDL:
package my_package is
type my_array_t is array (natural range <>) of std_logic_vector(N-1 downto 0);
end my_package
entity my_entity is
port(
my_input : in my_array_t(M-1 downto 0);
my_output : out my_array_t(M-1 downto 0);
);
end entity;
And the following SystemVerilog signal:
wire [N-1:0] my_input_s[M-1:0];
wire [N-1:0] my_output_s[M-1:0];
I believe these two types are completely equivalent. However, I can't go between each other without getting errors. Instantiating the VHDL module from SystemVerilog:
my_entity my_entity_inst(
.my_input(my_input_s),
.my_output(my_output_s)
);
The error I get is "formal port 'my_input' of type 'my_array_t' does not match with actual type 'logic'", similarly for the output signal. I tried different combination of array types in SystemVerilog (fully packed, fully unpacked) but none works. Note that in my case, I don't have the freedom of changing the VHDL declaration, I must find a way to make it work solely from SystemVerilog. Thus, this question can't help me.
How do I instantiate my VHDL module from SystemVerilog in the most straightforward way?

To be successful in instantiating VHDL in Verilog or SV stick to the basic types (types built into the original VHDL, not custom packages) in VHDL such as std_logic and std_logic vector.
For this case where you can't modify the VHDL file with custom port types, I recommend writing a VHDL wrapper (mydesign_wrapper.vhd) that instantiates the entity which uses the custom types and converts the ports to std_logic and std_logic_vector types for use at the top/entity of the wrapper design. Instantiate the new wrapper file in the Verilog or SystemVerilog file. An array of std_logic_vector would be represented as several std_logic_vector ports using the wrapper.
There is no standard for VHDL inside Verilog/SV, therefore support is limited and varies between tools, vendors, and versions.

Related

:[SYNTH 8-944] 0 definitions of operator sll and srr

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
--use IEE.NUMERIC_STD.ALL; --tried with this package aslo
architecture Behavioral of my_code is
signal DATA: signed(31 downto 0);
signal DATA_OUT signed(31 downto 0);
signal f: std_logic_vector(7 downto 0);
begin
DATA_OUT<=DATA srl (( f-1) sll '1');
end behavioral;
This is a small part of my code. I am using vivado 2018.2 .for the above line I am getting [synth 8-944] 0 definition of all operators.
I know Verilog but I am new to VHDL. should I use any other packages for that?
Please help me by providing a solution or "equivalent function" for that.
Your problem is because there are no sll and srl operators defined for the combination of types you are using. There are operators with signatures:
[unsigned, integer, return unsigned]
[signed, integer, return signed]
unsigned and signed are types in the numeric_std package. Neither of these operators is defined for a std_logic_vector in any standard package. (STD_LOGIC_ARITH and STD_LOGIC_UNSIGNED are non-standard. Don't use them.)
So, you have two choices:
i) (not recommended) convert all of your types so they fit either of the above signatures or
ii) (recommended) don't use the sll or srl operators. They are badly defined and can lead to more logic being synthesised than you need. Instead, use other VHDL operators (eg slicing/concatenation or mathematical). You're trying to do maths here, so I would perhaps use mathematical operators. You'll still need to use the numeric_std package, because you are doing maths. You can't do maths on std_logic_vector unless you use a non-standard package.

VHDL unconstrained records in system verilog testbenches

The design to be tested is written in VHDL and uses unconstrained records like this for its ports:
type forward_stream is record
data : std_ulogic_vector;
-- further members
...
end record;
These ports should now be driven from a systemverilog testbench. Is there any way to use the vhdl record type for the testbench signals? If so how do I constrain the record in systemverilog?
Or do I have to create a VHDL package that constrains the record and provides it as a type to be used in the testbench?
As HDL support varies largely between tools, I am asking about questasim (modelsim's big brother, same vendor so supposedly somewhat downward compatible) in particular.
Update
I gathered the following from the Questa SIM user manual for 10.4:
A record is mapped to a struct/packed struct (Table 9-5)
Subtypes are not mentioned in Table 9-5
I tried:
using a subtype in system verilog to connect to a port of the unconstrained type
using a subtype in system verilog to connect to a port of the unconstrained type with constraints
using a subtype in system verilog to connect to a port of the subtype
using the unconstrained type (without constraints) in system verilog to connect to a port of the unconstrained type with constraints.
Sample code:
VHDL:
library IEEE;
use IEEE.std_logic_1164.all;
package module_crosslanguage_pkg is
type t is record
s : std_ulogic_vector(2 downto 0);
c : std_logic_vector;
end record;
subtype t_s is t(c(1 downto 0));
end package;
use work.module_crosslanguage_pkg.all;
entity dummy_test is
port(a : in t); -- 1.
port(a : in t(c(1 downto 0))); -- 2.
port(a : in t_s); -- 3.
port(a : in t(c(1 downto 0))); -- 4.
end entity;
architecture a of dummy_test is
begin
end;
System Verilog
module modulebay_testbench();
import module_crosslanguage_pkg::*;
t_s testsignal;
t testsignal2;
dummy_test u(.a(testsignal)); -- 1., 2., 3.
dummy_test u(.a(testsignal2)); -- 4.
endmodule;
The error is always Fatal: (vsim-3362) The type of VHDL port 'a' is invalid for Verilog connection (1st connection).
Yes, see Sharing User-Defined Types in the Questa User Manual. It shows how to import packages defined in one language and use/import them in the other.

VHDL type conversion - found 4 possible definitions

I am trying convert two std_logic bits to an integer as follows
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
USE IEEE.numeric_std.ALL;
ENTITY TEST IS
PORT (sw1, sw0 : IN std_logic;
x : OUT integer RANGE 3 DOWNTO 0);
END ENTITY TEST;
ARCHITECTURE dflow OF TEST IS
SIGNAL mes_sel : integer RANGE 3 DOWNTO 0;
BEGIN
mes_sel <= to_integer(unsigned(std_logic_vector(SW1 & SW0)));
x <= mes_sel;
END ARCHITECTURE dflow;
but the compiler does not like the mes_sel assignment. I get the following compiler error message:
Error (10327): VHDL error at Q4.vhd(92): can't determine definition of operator ""&"" -- found 4 possible definitions
Can I not concatenate 2 bit of std_logic to a vector and then convert? Or is it something else?
regards
D
The error message tells you roughly what's wrong, and it's not a problem with the assignment.
GHDL gives a better diagnosis:
ghdl -a test.vhd
test.vhd:13:57: can't resolve overload for operator "&"
test.vhd:13:57: possible interpretations are:
../../src/ieee/numeric_std.v93:66:18: array type "signed"
../../src/ieee/numeric_std.v93:65:20: array type "unsigned"
../../src/ieee/std_logic_1164.v93:69:30: array type "std_logic_vector"
../../src/ieee/std_logic_1164.v93:54:31: array type "std_ulogic_vector"
ghdl: compilation error
VHDL allows overloaded operators, distinguishable by the types of their arguments (in this case, std_logic) and their return types, (in this case ... well... what?)
There are apparently 4 types which have a std_logic_vector() type conversion function declared on them, as well as a & operator taking two std_logic arguments; and ghdl (unlike whatever tool you're using) helpfully lists them.
In such cases, VHDL (unlike some other languages) insists that you pick one, rather than arbitrarily making a hidden (and possibly wrong) choice for you.
You can do this with a type mark. As you actually want an unsigned, the obvious choice is unsigned'() (note the "'" symbol, also used for attributes).
mes_sel <= to_integer(unsigned'(SW1 & SW0));
Note that if VHDL allowed anything simpler, like to_integer(SW1 & SW0) it would be positively dangerous as there is nothing to distinguish between signed and unsigned conversions, making the conversion at least non-obvious, and quite possibly wrong.

VHDL: Mapping a slice of an output to a signal

I want to map the lower bit (bit0) of a 32 bit output port to a signal and leave the upper bits unconnected (OPEN). Is there a way to treat this mapping as an aggregate?
I've tried the following to no avail:
port map (
some_output => ( 0 => sig_1, others => OPEN)
);
The below is not a valid answer, since it does not adhere to the VHDL standard. This "answer" is however kept here, and not deleted, since it shows what construction to avoid for tool compliance, since some tools apparently accept this non-standard compliant VHDL code.
Example of port mapping without association of all scalar subelement, which is accepted by Altera Quartus II and Mentor ModelSim in some cases, but is also likely to result in warning or error:
port map(
some_output(0) => sig_1,
-- some_output others are simply not included in port mapping
So, as David Koontzs point out in the comment, the VHDL standard (IEEE Std 1076-2008) section "6.5.7 Association lists" describes:
... every scalar subelement of the explicitly declared interface object shall be associated exactly once with an actual (or subelement thereof) in the same association list, and all such associations shall appear in a contiguous sequence within that association list. Each association element that associates a slice or subelement (or slice thereof) of an interface object shall identify the formal with a locally static name.
So it is not valid to only associate some of the scalar subelements, since the standard says "every scalar subelement", and open can't be used for the remaining scalar subelements, since the standard says "Each association element that associates a slice ... of an interface object shall identify the formal with a locally static name.".
Another solution is this:
signal my_vector : STD_LOGIC_VECTOR(3 downto 0);
signal my_vector_float : STD_LOGIC_VECTOR(3 downto 0);
port map (
[...]
some_output(3 downto 0) => my_vector,
some_output(7 downto 4) => my_vector_float,
[...]
);
You can now setup some report filter rules to silence all warning concerning *_float signals.

std_logic_signed is used but not declared

I am new to VHDL. I am trying to use a std_logic_signed signal but I keep getting the error "std_logic_signed is used but not declared". As far as I can tell I have used the right libraries but googeling the error resulted in a lot of conflicting answers.
Here is my sample program:
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_arith.all;
entity bird is
end entity bird;
architecture arch of bird is
--Declare signals
signal speed : std_logic_signed (7 downto 0);
begin
end architecture arch;
What is causing the error and how do I fix it?
Because the type name is SIGNED:
grep -i signed std_logic_arith.vhdl
std_logic_arith.vhdl: type SIGNED is array (NATURAL range <>) of STD_LOGIC;
...
There isn't a type declared named std_logic_signed.
Instead of declaring speed with a type mark of std_logic_signed use signed:
--Declare signals
signal speed : signed (7 downto 0);

Resources