General Description: A problem that results in the creation of incorrect logic has been identified in VHDL Compiler. The problem may occur when a constrained integer subtype with a non-negative "downto" range is used in a comparison.
This problem has been traced to changes in VHDL Compiler as part of the turbo enhancements that spee up elaboration time. It can be reliably detected during post-synthesis simulation.
Here are the two scenarios that can result in VHDL Compiler producing incorrect logic (note that the problem does not exist in Verilog):
In the first scenario, a "for loop" index is compared to a constrained integer with a non-negative downto range, as shown here:
signal addr : integer range A downto B; -- where A > 0 and B >= 0
This situation produces incorrect logic in the 1998.02* (1998.02, 1998.02-1, and 1998.02-2) release. Note that the loop index is implicitly treated as an unconstrained integer by VHDL Compiler.
Scenario 1 (Incorrect logic in the 1998.02* release): ... signal addr : integer range 7 downto 0; ... ... process (addr, a, b, c) begin for i in 3 downto 0 loop if (addr = i ) then -- INTEGER TO INTEGER COMPARISON -- AS THE INDEX "i" OF THE "for loop" -- IS ALWAYS TREATED AS AN INTEGER. THE -- OTHER INTEGER HAS A NON-NEGATIVE -- DOWNTO RANGE. PLEASE NOTE THAT THE -- DOWNTO RANGE IN THE FOR LOOP -- STATEMENT IS NOT A PROBLEM. ... ... end behavior;
Although it is not true for all cases, you may get the following HDL-395 warning message when incorrect logic is produced:
Warning: The statement in routine %s line %d in file %s is never reached. (HDL-395)
If you are trying to generate flip-flops within the for loop, you might find that some of the flip-flops are missing as a result of the incorrect logic.
The second scenario is when two signals, variables, or ports of type "integer" are compared, and only one of the integers has a non-negative downto range. For example, compare "addr1" and "addr2":
"addr1" is an integer of range A downto B, where A > 0 and B >= 0.
"addr2" can be: an integer, an integer of range C downto D, or an integer of range D to C, where D < 0 and C is any number.
This will produce incorrect logic in the 1997.08* and 1998.02* releases.
Scenario 2 (Incorrect logic in the 1997.08* and 1998.02* releases):
... signal addr1 : integer; signal addr2 : integer range 7 downto 0; ... ... process (addr1, addr2, a, b, c); begin if (addr1 /= addr2) then -- INTEGER TO INTEGER COMPARISON -- WHERE ONE OF THE INTEGERS HAS -- A NONNEGATIVE DOWNTO RANGE.
... ... end behavior;
Solution
The following two work-arounds will resolve this problem. One sacrifices some of the speedup caused by turbo enhancements to the elaboration process; the other requires a minor code modification.
1. Use the following hidden variable at the dc_shell prompt to disable a part of the turbo speedups. Make sure that you set this variable before reading or analyzing/elaborating the VHDL:
hdlin_accel_level = 4
2. The comparison of integers creates problems for a non-negative downto range. Change the 7 downto 0 range of integers in previous scenarios to 0 to 7, as shown here.
Scenario 1: signal addr : integer range 0 to 7;
Scenario 2: signal addr2 : integer range 0 to 7;
This problem was fixed in the 1998.08 release; this corresponds to FPGA Express 2.1.1 and Foundation F1.5.