constant connection on instance pin in vhdl'87 - vhdl

I have following simple testcase :
library ieee;
use ieee.std_logic_1164.all;
entity top is
end top;
architecture top of top is
component foo
port (A : std_logic_vector(1 downto 0));
end component;
begin
inst : foo port map (A(1) => '0', A(0) => '0');
end top;
------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
entity foo is
port (A : std_logic_vector(1 downto 0));
end foo;
architecture foo of foo is
begin
end foo;
When running modelsim on this, it runs fine. But, when I run modelsim with option '-87', it gives me error that Error: top.vhd(13): (vcom-1451) Actual (enumeration literal '0') for formal "A" is not signal name. I am not getting this. Is this some illegal RTL in VHDL'87?
If this is not supported in VHDL'87, then what would be right way to connect a constant to instance pin.

Looking in Modelsim's Verror messages:
vcom Message # 1451: The actual designator is not a static signal
name, it is an expression. In a VHDL 1987 port map, the actual
designator in an association element must be either a static signal
name or a conversion function call whose only argument is a static
signal name. In a subprogram association list in any VHDL language
version, the actual associated with a class SIGNAL subprogram
parameter must be a static signal name.
Later versions of VHDL allow
flexibility in the actual in a port map.
Try using the -93, -2002, or -2008 switch to vcom.
[DOC: IEEE Std 1076-1987 VHDL LRM - 2.1.1.2 Signal parameters,
4.3.3.2 Association Lists]
[DOC: IEEE Std 1076-1993 VHDL LRM - 2.1.1.2 Signal parameters]
So, yes there's a difference in what is valid for an an actual in a port association. The -1993 'liberalization' would also be applicable on later versions (-2002, -2008).
The actual needs to be named and not simply an expression. Inputs with default values can be left open.

Related

vhdl ERRROR: Attribute "range" requires a constrained array prefix

Two questions:
how to get rid of the warning: "Shared variables must be of a protected type." while keeping it as a "shared variable"?
How to fix Attribute "range" requires a constrained array prefix?
First of all, what is a constrained array prefix?
$ vcom.exe -2002 -l test3.vhd
** Warning: test3.vhd(14): (vcom-1236) Shared variables
must be of a protected type.
** Error: test3.vhd(20): (vcom-14402) Attribute "range"
requires a constrained array prefix.
library ieee;
use ieee.std_logic_1164.all;
entity test3 is
end entity;
architecture beh of test3 is
constant dw :integer := 8;
constant depth :integer := 128;
type mem_t is array (integer range<>) of std_logic_vector(dw-1 downto 0);
shared variable ram_block :mem_t(0 to depth-1);
begin
process
variable i:integer;
begin
for i in mem_t'range loop
report integer'image(i);
end loop;
end process;
end architecture;
A protected type in VHDL, is similar to a class in OO programming, where it can have member methods and it can retain state. Since 2002, it is required that shared variables must be of a protected type. By default, most tools only throw a warning to maintain backwards compatibility unless you turn on strict rule checking
So you have two options to remove the warning
revert to VHDL 1993 standard.
Create a protected type.
Your example shows no need for a shared variable. It could be made into a normal (non shared) variable inside the process.
Question 2, I found... But Question 1, I'm still not sure about..
architecture beh of test3 is
constant dw :integer := 8;
constant depth :integer := 128;
type mem_t is array (integer range<>) of std_logic_vector(dw-1 downto 0);
shared variable ram_block :mem_t(0 to depth-1);
begin
process
variable i:integer;
begin
report "left:" & integer'image( ram_block'left);
report "right:" & integer'image( ram_block'right);
for i in ram_block'range loop
report integer'image(i);
end loop;
wait;
end process;
end architecture;

Can't compile with VHDL 2008 Quartus Prime

I'm using Quartus Prime Lite Edition and I want to use unary operator nand on std_logic_vector like this
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity example1 is
port(
BIN : in std_logic_vector (7 downto 0);
result : out std_logic
);
end;
architecture Beh of example1 is
begin
result <= nand BIN;
end Beh;
I tried to follow this instructions, changed VHDL version under VHDL Input in Compiler Settings. Still no effect and getting:
Error (10500): VHDL syntax error at lab2.vhd(16) near text "nand"; expecting "(", or an identifier ("nand" is a reserved keyword), or unary operator
Quartus Prime Lite does not support VHDL 2008.
https://www.intel.com/content/dam/www/programmable/us/en/pdfs/literature/po/ss-quartus-comparison.pdf
This error is coming as "nand" requires two inputs.
From your question, it appears to me that you want to perform the bitwise nand operation on the input.
If yes, you can replace architecture as follows. I am assuming that you are familiar with the "generate for" syntax!
architecture Beh of example1 is
--Signals for Storing Intermediate Bitwise Values
signal temp1:std_logic_vector(3 downto 0);
signal temp2:std_logic_vector(1 downto 0);
begin
-- First level of NAND Operations
label_1: for i in 0 to 3 generate
temp1(i)<=BIN(2*i) nand BIN(2*i+1);
end generate label_1;
-- Second level of NAND Operations
label_2: for j in 0 to 1 generate
temp2(j)<= temp1(2*j) nand temp1(2*j+1);
end generate label_2;
-- Getting the Final Output
result<= temp2(1) nand temp2(0);
end Beh;
Thanks,
Dr. Ray

Aggregate assignment to access type is not static?

I have the following code:
library IEEE;
use IEEE.std_logic_1164.all;
entity static_test is
end entity;
architecture sim of static_test is
type rec_t is record
sl : std_logic;
slv : std_logic_vector(6 downto 0);
end record;
type rec_ptr_t is access rec_t;
begin
process
variable ptr : rec_ptr_t;
begin
ptr := new rec_t;
(ptr.sl, ptr.slv) := std_logic_vector'(x"00");
wait;
end process;
end architecture sim;
And I get the following errors from ActiveHDL:
Error: COMP96_0309: static_test.vhd : (28, 6): Expression in element association of the aggregate must be a locally static name that denotes a variable.
Error: COMP96_0309: static_test.vhd : (28, 14): Expression in element association of the aggregate must be a locally static name that denotes a variable.
I cannot find the LRM section that specifies an aggregate assignment needs to be locally static, and I also dont understand why ptr.sl or ptr.slv is not considered locally static. The lengths are known in the type. Is it just that an access type cannot ever be considered locally static (it kind of makes sense to me).

Custom Type as VHDL 2008 Generic

I want to create a custom type in my generic section of my entity using VHDL-2008. However I get an error immediately in Modelsim with this code. The error is:
** Error: C:/Projects/source/My_Mux.vhd(35): near "is": expecting ';' or ')'
Note that Line 35 is the type t_Array below:
entity My_Mux is
generic (
g_MUX_INPUTS : integer := 2;
type t_Array is array (0 to g_MUX_INPUTS-1) of std_logic_vector(7 downto 0)
);
port (
i_Select : in std_logic_vector(1 downto 0);
i_Mux_Data : in t_Array;
o_Data : out std_logic_vector(7 downto 0)
);
end entity My_Mux;
architecture RTL of My_Mux is
begin
o_Data <= i_Mux_Data(0) when i_Select = "00" else i_Mux_Data(1);
end architecture RTL;
I looked into creating a special function that I define in my generic portion of my code. But that requires that I overload the function in the instantiating module, which I really did not want to have to do, it seems needlessly complicated. If I could create a custom type in the generic it would solve my problem. Possible using VHDL-2008?
How would you expect to have type compatibility between the formal and actual if they declaration of a type were actually made in a generic declaration?
Each declaration in VHDL is unique, not by name but by declaration occurrence. What declaration the name references depends on scope and visibility. Both (all) places a name is used have to be able to reach the same declaration.
How a generic type is declared is found in IEEE Std 1076-2008 6.5.3 Interface type declarations:
An interface type declaration declares an interface type that appears as a generic of a design entity, a component, a block, a package, or a subprogram.
interface_type_declaration ::=
interface_incomplete_type_declaration
interface_incomplete_type_declaration ::= type identifier
An interface type provides a means for the environment to determine a type to be used for objects in a particular portion of a description. The set of values and applicable operations for an interface type may be determined by an associated subtype in the environment. The manner in which such associations are made is described in 6.5.7.
And the important thing to note is that is an incomplete type declaration, where the actual specifies a preexisting type with a subtype constraint (6.5.6.2):
The subtype denoted by a generic type is specified by the corresponding actual in a generic association list. It is an error if no such actual is specified for a given formal generic type (either because the formal generic is unassociated or because the actual is open).
Because that association is with a previously declared type there is little difference with doing the same thing the -1993 way:
library ieee;
use ieee.std_logic_1164.all;
package my_package is
type my_array is array (natural range <>) of std_logic_vector(7 downto 0);
end package;
library ieee;
use ieee.std_logic_1164.all;
use work.my_package.all;
entity My_Mux is
generic (
g_MUX_INPUTS: integer := 2
--type t_Array is array (0 to g_MUX_INPUTS-1) of
-- std_logic_vector(7 downto 0)
);
port (
i_Select: in std_logic_vector(1 downto 0);
-- i_Mux_Data: in t_Array;
i_Mux_Data: in my_array (0 to g_MUX_INPUTS - 1);
o_Data : out std_logic_vector(7 downto 0)
);
end entity My_Mux;
architecture RTL of My_Mux is
begin
o_Data <= i_Mux_Data(0) when i_Select = "00" else i_Mux_Data(1);
end architecture RTL;
There's an added package that has a type declaration my_array which is an unbound (partially constrained) multidimensional array type.
This allows the use of the package my_package to specify the type of the actual:
library ieee;
use ieee.std_logic_1164.all;
use work.my_package.all;
entity my_mux_tb is
end entity;
architecture foo of my_mux_tb is
constant MUX_INPUTS: natural := 2;
signal i_Select: std_logic_vector (1 downto 0);
signal i_Mux_Data: my_array (0 to MUX_INPUTS -1);
signal o_Data: std_logic_vector(7 downto 0);
begin
DUT:
entity work.My_mux
generic map (
g_MUX_INPUTS => MUX_INPUTS
)
port map (
i_Select => i_Select,
i_Mux_Data => i_Mux_Data,
o_Data => o_Data
);
end architecture;
The two examples above analyzed in order, elaborate and the testbench simulates (while doing nothing particular interesting besides telling us the subtype constraint is passed on the port actual).
The custom type would be required to be accessible to both the component or entity instantiation and the place the port actual is declared.
Using a generic type would allow you to remove the my_package use clause from the my_mux context clause, relying on the actual association instead.
You can also bind the type at elaboration time without switching the package (or relying on package instantiation in -2008 with it's own generics).

Conversion function "To_bit" must have exactly one formal parameter

I am getting above error while running modelsim on a VHDL Testcase and I am unable to understand why is it an error.
The Testcase:
LIBRARY IEEE;
Use ieee.std_logic_1164.all;
entity a is
port (in11 : in std_logic
);
end a;
Architecture a of a is:
component b_1
port ( in1 : in bit);
end component;
begin
inst : b_1 port map ( in1=> **to_Bit**(in11));
end a;
That's a modelsim error, actually it should report that you are not allowed to use this function as actual in a port map, this works:
LIBRARY IEEE; Use ieee.std_logic_1164.all;
entity a is port (in11 : in std_logic ); end a;
architecture a of a is
signal inBit : Bit;
component b_1 port ( in1 : in bit); end component;
begin
inBit <= to_bit(in11);
inst : b_1 port map ( in1=> inBit); end a;
There are restrictions that apply to actuals in port maps, c.f. vhdlref:
The actual, if a port or signal, must be denoted by a static name
(see 6.1). The actual, if an expression, must be a globally static
expression (see 7.4).
The thing is, both cases should be globally static...
VHDL-93 allows type conversions and conversion functions in association lists.
A conversion function is a special case of a function with only one argument.
Let's look at the declaration of to_bit:
function to_bit(s : std_ulogic; xmap : bit := '0') return bit;
Although to_bit(s) looks like a valid conversion function, it's not, because the declaration contains two arguments.
The second argument xmap is used as the result when is_x(s) is true.
This is not a ModelSim bug, but maybe the error message is a bit cryptic. ModelSim figures that to_bit is meant to be a conversion function, but refuses to use it, because it has a second argument, and is thus not a valid conversion function.
A simple wrapper function can solve the problem:
function to_bit(s : std_ulogic) return bit is
begin
return to_bit(s, '0');
end;
Note that the function can also have the name to_bit, because VHDL supports function overloading. It would be nice to have this in the package std_logic_1164.

Resources