VHDL unconstrained records in system verilog testbenches - vhdl

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.

Related

Instantiate VHDL entity with 2D array from SystemVerilog

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.

GHDL simulator doesn't support vhdl attributes without error?

I wrote some vivado RTL and then added some vhdl attributes to the ports of the entity to define the interface to Xilinx Vivado tool as follows:
library ieee;
use ieee.std_logic_1164.all;
entity vivado_rtl_island is
port(
-- Clocks
i_m50_clk :in std_logic;
i_m50_rst :in std_logic;
-- APB Command Inteface
s_paddr :in std_logic_vector(31 downto 0);
s_psel :in std_logic;
s_penable :in std_logic;
s_pwrite :in std_logic;
s_pwdata :in std_logic_vector(31 downto 0);
s_pready :out std_logic;
s_prdata :out std_logic_vector(31 downto 0);
s_pread :out std_logic;
s_pslverr :out std_logic
);
end entity;
architecture rtl of vivado_rtl_island is
-- Define APB Interface for "Vivado IP Integrator"
ATTRIBUTE X_INTERFACE_INFO: STRING;
ATTRIBUTE X_INTERFACE_INFO of s_paddr: SIGNAL is "xilinx.com:interface:apb:1.0 APB_S PADDR";
ATTRIBUTE X_INTERFACE_INFO of s_psel: SIGNAL is "xilinx.com:interface:apb:1.0 APB_S PSEL";
ATTRIBUTE X_INTERFACE_INFO of s_penable: SIGNAL is "xilinx.com:interface:apb:1.0 APB_S PENABLE";
ATTRIBUTE X_INTERFACE_INFO of s_pwrite: SIGNAL is "xilinx.com:interface:apb:1.0 APB_S PWRITE";
ATTRIBUTE X_INTERFACE_INFO of s_pwdata: SIGNAL is "xilinx.com:interface:apb:1.0 APB_S PWDATA";
ATTRIBUTE X_INTERFACE_INFO of s_pready: SIGNAL is "xilinx.com:interface:apb:1.0 APB_S PREADY";
ATTRIBUTE X_INTERFACE_INFO of s_prdata: SIGNAL is "xilinx.com:interface:apb:1.0 APB_S PRDATA";
ATTRIBUTE X_INTERFACE_INFO of s_pslverr: SIGNAL is "xilinx.com:interface:apb:1.0 APB_S PSLVERR";
begin
end architecture;
There I try to compile the above rtl using GHDL as follows:
$ ghdl -a --std=08 --ieee=synopsys --work=work vivado_rtl_island.vhd
GHDL produces the following error:
vivado_rtl_island.vhd:28:33: no "s_paddr" for attribute specification
vivado_rtl_island.vhd:29:33: no "s_psel" for attribute specification
vivado_rtl_island.vhd:30:33: no "s_penable" for attribute specification
vivado_rtl_island.vhd:31:33: no "s_pwrite" for attribute specification
vivado_rtl_island.vhd:32:33: no "s_pwdata" for attribute specification
vivado_rtl_island.vhd:33:33: no "s_pready" for attribute specification
vivado_rtl_island.vhd:34:33: no "s_prdata" for attribute specification
vivado_rtl_island.vhd:35:33: no "s_pslverr" for attribute specification
However, when I compile this with modelsim, it doesn't produce an error.
Does anybody know how to work around this problem in GHDL so that I can add these attributes and the simulator will ignore them and not produce and error?
See IEEE Std 1076-2008 7.2 Attribute specification, paragraph 9:
An attribute specification for an attribute of an entity declaration, an architecture, a configuration, or a package shall appear immediately within the declarative part of that declaration. Similarly, an attribute specification for an attribute of an interface object of a design unit, subprogram, block statement, or package shall appear immediately within the declarative part of that design unit, subprogram, block statement, or package. Similarly, an attribute specification for an attribute of an interface object of a design unit, subprogram, block statement, or package shall appear immediately within the declarative part of that design unit, subprogram, block statement, or package. ...
The design unit is the entity declaration (3.2 Entity declarations), a primary unit (13.1 Design units). This semantic restriction has been in place in every IEEE Std 1076 revision (-1987 through -2008, prior to -2008 found in 5.2 Attribute specification). Modelsim is wrong to 'compile' your specifications.
Xilinx's Vivado synthesis historically takes advantage of the Modelsim behavior. What's funny here is Vivado inconsistently adheres to the semantic requirement of the first quoted sentence of 7.2 above which is also found in earlier revisions but not the second. You can declare an attribute on an entity in the entity declarative part while Vivado at least historically required specify attributes on ports in the architecture declarative part.
All isn't lost when using ghdl. There's a command line argument that can be passed during analysis to relax various rules to match Modelsim's behavior where relied on by third party tools.
ghdl -a --std=08 --ieee=synopsys -frelaxed-rules --work=work vivado_rtl_island.vhdl
vivado_rtl_island.vhdl:28:33:warning: attribute for port "s_paddr" must be specified in the entity [-Wspecs]
vivado_rtl_island.vhdl:29:33:warning: attribute for port "s_psel" must be specified in the entity [-Wspecs]
vivado_rtl_island.vhdl:30:33:warning: attribute for port "s_penable" must be specified in the entity [-Wspecs]
vivado_rtl_island.vhdl:31:33:warning: attribute for port "s_pwrite" must be specified in the entity [-Wspecs]
vivado_rtl_island.vhdl:32:33:warning: attribute for port "s_pwdata" must be specified in the entity [-Wspecs]
vivado_rtl_island.vhdl:33:33:warning: attribute for port "s_pready" must be specified in the entity [-Wspecs]
vivado_rtl_island.vhdl:34:33:warning: attribute for port "s_prdata" must be specified in the entity [-Wspecs]
vivado_rtl_island.vhdl:35:33:warning: attribute for port "s_pslverr" must be specified in the entity [-Wspecs]
You can add the command line flag -frelaxed-rules and the errors will be converted to warnings.
The default ghdl behavior is changed for standard revision -2008. You'd note that without specifying --std=08 the default standard compliance is --std=93c which includes -frelaxed-rules and is otherwise compatible with `--std=93 (-1993). There isn't a -2008 revision with relaxed rules included.
The reason behind the semantic restriction would stem from a leading (at the time -1987) vendor not being able to implement specifying a user attribute on a port without having direct access to the port declaration. While that vendor is likely no longer providing VHDL products the restriction remains.
We find various instances of of Modelsim effectively trying to steer the standard by market share influence (they have a command line -pendanticerrors argument changing a lot of warnings to errors).
ghdl development follows their lead with the exception that strict compliance with the standard is the norm (--std=93c as a default notwithstanding) with command line arguments enabling warnings instead of errors.
The reasoning for this would be that those implementing VHDL tend to do so from the standard and not by reverse engineering the vendor with the greatest market share.
The -frelaxed-rules description may not be complete in ghdl documentation. Mention is found in the sections on VHDL standards as well as other sections.
Xilinx has been made aware of the issue. Modelsim undoubtedly knows where they vary from the standard and there currently is no vendor participation in the VHDL standard revision process.
Looking through the ghdl source tree ghdl-0.35 was released on Dec 14, 2017, and Issue 525 had a fix on Feb 7, 2018 (see src/vhdl/sem_specs.adb) to add port attributes to the architecture declarative part with -frelaxed-rules to provide the present functionality regardless of --std=08 (during the ghdl-0.36 developement cycle).
Also see Issue 838 Xilinx Vivado and Modelsim support attributes on ports differently than GHDL, on github wherein the OP sought a second opinion stating this answer is valid.
You are using VHDL2008, apparently.
With VHDL 2008, entity port attributes must go into the entity definition, i.e. you need to move your attributes before the end entity statement.
Compile like this with GHDL:
ghdl.exe -a -frelaxed-rules --std=08 --ieee=synopsys --work=work ./vivado_rtl_island.vhd
And move port attributes to Architecture block...
then it will work consistently with both Xilinx Vivado and GHDL.

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);

VHDL alias syntax "<< ... >>"

I'd like to understand the syntax used in the line of code below where an alternate name is created using an ALIAS declaration. Specifically, I'd like to know what the << and >> imply. An example alias statement is,
alias x2_dac_data is
<< signal server.x2_dac_data : std_logic_vector(23 downto 0) >>;
where server is an instantiated component and x2_dac_data is a signal with the component, but not listed in the port declaration.
I've reviewed Pedroni's text and a course guide, neither of which reference the << ... >> syntax as it relates to alias.
Thanks
The double Less-Thans and double Greater characters (<<, >>) enclose an External Name, which is a path name to a object (e.g. signal, constant, variable) through a design model's hierarchy. The intended use is for design verification, allowing a testbench to reach objects not visible at the top level of a design.
See Peter Ashenden and Jim Lewis The Designer's Guide to VHDL (3rd Ed.), Section 18.1 External Names and Doulos VHDL-2008: Easier to use, Hierarchical Names, or IEEE Std 1076-2008, 8.7 External names.
There's an example on Page 561 of The Designer's Guide to VHDL:
alias duv_data_bus is
<<signal .tb.duv_rtl.data_bus : std_ulogic_vector(0 to 15)>>;
The syntax is described on Page 560. Pages 559-562 are visible in the Google Book preview. The example found in The Designer's Guide to VHDL dealing with external names is also found in Chapter 2, Section 2.1 External Names of VHDL 2008 Just the New Stuff by the same authors and while without the EBNF syntax description goes further into the philosophy behind external names. Unfortunately the book's Google Book preview doesn't reach Section 2.1. Jim Lewis is organizing the P1076 Study Group of the IEEE VHDL Analysis and Standardization Group (VASG) responsible for developing the next revision of IEEE Std 1076-201X. Peter Ashenden is a long time contributor to the VHDL standardization effort as well.
A better solution than aliases to hierarchical signal references in packages: using a package to share signals between bfm-procedures and testbench toplevel. Example:
library ieee;
use ieee.std_logic_1164.all;
--VHDL 2008 with questasim
package bfm is
signal tb_ii_a : std_logic;
signal tb_ii_b : std_logic;
signal tb_oo_c : std_logic;
procedure wiggle;
end package;
package body bfm is
procedure wiggle;
begin
tb_oo_c <= force in '1';
wait for 10 ns;
tb_oo_c <= force in '0';
wait for 10 ns;
tb_oo_c <= force in tb_ii_a and tb_ii_b;
end procedure;
end package body;
library ieee;
use ieee.std_logic_1164.all;
use std.textio.all;
use std.env.all;
library work;
use work.bfm.all;
entity tb;
end tb;
architecture tb_dut1 of tb is
begin
dut : entity work.dut port map(
oo_a => tb_ii_a, -- output of dut input of tb bfm
oo_b => tb_ii_b, -- output of dut input of tb bfm
ii_c => tb_oo_c -- input of dut output of tb bfm
);
testcase : process
begin
wiggle;
wait for 100 ns;
std.env.stop(0);
end process;
end architecture;

VHDL syntax for arrays of clocks (accepted by synthesis but not Active-HDL simulator)

I've a problem with some VHDL syntax in some old code that I want to reuse. It is accepted by the synthesis tool (Synplify) but the simulator (Aldec Active-HDL 8.3) gives the following error. (Note: This construction was accepted by a previous version of this simulator).
#Error: COMP96_0228: buffered_data.vhdl : (19, 28): The actual must be denoted by a static signal name, if the actual is associated with a signal parameter of any mode.
I get that the error doesn't like the (i) in the signal clk(i) but I don't want to unroll the loop to (0),(1),etc because it's used in several different configurations for different port sizes and I'm sure there must be a way to describe this.
My solution so far is to encapsulate one instance in it's own entity/arch hierarchy and use a "generate" to instantiate once for each port but I don't like it. Any better ideas?
Very simplified example showing exactly my issue. (The intent is to ensure that data is first clocked into the FPGA using its own associated clock before anything else)
library IEEE;
use IEEE.STD_LOGIC_1164.all;
entity input_buffer is
port(
clk : in std_logic_vector;
data_in : in std_logic_vector;
data_out : out std_logic_vector
);
end input_buffer;
architecture rtl of input_buffer is
constant c_NumOfPorts : integer := 3;
begin
p_process: process(clk)
begin
for i in 0 to c_NumOfPorts-1 loop
if rising_edge(clk(i)) then -- error here
data_out(i) <= data_in(i);
end if;
end loop;
end process;
end rtl;
If you change the loop inside the process into a generate statement outside the process, it works fine in ModelSim (I don't have Aldec available), and IMHO seems cleaner than a single process with a bunch of clocks. I would also typically use a generic to define the port widths, rather than pulling them in as a constant inside the architecture, but I figure you've got some reason for doing it that way:
library IEEE;
use IEEE.STD_LOGIC_1164.all;
entity input_buffer is
port(
clk : in std_logic_vector;
data_in : in std_logic_vector;
data_out : out std_logic_vector
);
end input_buffer;
architecture rtl of input_buffer is
constant c_NumOfPorts : integer := 3;
begin
gen : for i in 0 to c_NumOfPorts-1 generate
begin
p_process: process(clk(i))
begin
if rising_edge(clk(i)) then -- error here
data_out(i) <= data_in(i);
end if;
end process;
end generate;
end rtl;
FWIW, I get the same with Modelsim:
Model Technology ModelSim PE vcom 10.0a Compiler 2011.02 Feb 20 2011
-- Loading package STANDARD
-- Loading package TEXTIO
-- Loading package std_logic_1164
-- Compiling entity input_buffer
-- Compiling architecture rtl of input_buffer
** Error: clk.vhd(19): (vcom-1450) Actual (indexed name) for formal "s" is not a static signal name.
** Error: clk.vhd(25): VHDL Compiler exiting
As an aside - is there a reason for your use of the constant and not just doing this?
for i in clk'range loop
But no actual answer has occurred to me yet, sorry!

Resources