3

When I try to synthesize my VHDL design (using Xilinx ISE Design Suite), I get the message:

WARNING:Cpld - The signal(s) 'e' are in combinatorial feedback loops.
   These signals may cause hazards/glitches. Apply the NOREDUCE parameter to the
   hazard reduction circuitry.
   Timing analysis of paths involving this node may be inaccurate or incomplete.

This is confusing as my design simply consists of a counter 'c' that increases on each clock tick and some signals that are derived from it in a way where I don't believe any loop can exist, to form an output signal. Here's the code:

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;

entity foo is
    port (
        CLK : in std_logic;
        A : out std_logic_vector(1 downto 0)
    );
end foo;

architecture foo_arch of foo is

signal b : unsigned(1 downto 0);
signal e : std_logic;
signal c : unsigned(1 downto 0) := "00";
begin
   process (CLK, c)
    begin
        if rising_edge(CLK) then
            c <= c + 1;
        end if;
    end process;

    b <= c(1 downto 0) - 1;
    e <= '1' when b(1 downto 0) = 0 else '0';
    A <= std_logic_vector(b(1 downto 0)) when e = '1' else "ZZ";
end foo_arch;

So you can see

  • b is derived from c
  • e is derived from b
  • A (the output) is derived from b and e

What's the problem? Am I going crazy? Am I doing something incredibly stupid or is the synthesizer playing games with me?

Voltage Spike
  • 75,799
  • 36
  • 80
  • 208

4 Answers4

2

It seems this is a bug in the Xilinx ISE VHDL synthesis tool. I was able to work around it by interposing a D-type flip-flop in the e signal. This delays the signal by one clock cycle, but, fortunately, it does not matter in my application.

1

Nice self-contained example and I agree with your analysis ... you are going crazy. No, wait ... in the good old days I'd be submitting this as a probable bug on Webcase. Now, you can try asking for comments from Xilinx staff on their own forum.

One not-too-hygienic construct : initialising c to "00" in the declaration is normally supported by Xilinx synthesis tools but possibly not for all architectures : I'd suggest adding a Reset input and assigning c <= "00"; in an if Reset clause, in case XST isn't obeying the initial value here and thus can't infer an initial state.

Other things to try

  • for some target devices, XST uses one VHDL parser with one set of bugs, for other target devices it uses a different parser. You can switch between parsers (possibly not for all targets) by setting the "Use New Parser - Yes" tick box (under Synthesis / Properties / Advanced View").
  • Vivado appears to have yet another VHDL parser you could try.
0

The warning arises because the order in which the signals b,e,A are assigned to is not defined. Under synthesis you are likely to get glitches with this circuit due to the differing delays. This is a warning because a subsequent circuit cannot rely on the dependencies between these signals beeing in a particular order. Without knowing what you are using this I don't know if it is correct or not.

John
  • 470
  • 2
  • 5
  • I have to disagree. I now believe the code is okay and it's just a bug in the synthesis tool. I don't see why there should be any glitches - there is no circular dependency between b, e, A, they all well defined. – Jiri Svoboda Aug 07 '17 at 11:14
0

This is not a bug in the synthesis tool, the warning is correct.

If you draw the circuit described by the code, you will see that 'b' is an input to a mux with output 'A' while simultaneously driving the mux selector via 'e' combinatorially.

schematic

simulate this circuit – Schematic created using CircuitLab

This, as stated in the warning, may result in glitches. The reason it is only a warning and not an error is because it may not manifest into a non-functioning system because that of course depends on how these signals are used elsewhere in the design.

But here is an example of a possible glitch:

State 0: b = "00", e = '1', A = "00"; State 1: b = "01", e = '0', A = "zz".

When transitioning from S0 to S1, there will be a delay between the updating of 'e' after the updating of 'b'. During this small delay, 'A' will hold the value of 'b' = "01". This is a glitch that the synthesis tool is warning about.

It may be the case that in the parent module that instantiates this component that 'A' is registered. In this case, the warning may disappear when synthesising the overall design, but in isolation, the output 'A' will contain glitches as per my example.

In conclusion, this warning would be avoided if recommended design practices such as registering outputs (i.e. registering 'A') were followed.

The code could also be simplified to:

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;

entity foo is
    port (
        CLK : in std_logic;
        A : out std_logic_vector(1 downto 0)
    );
end foo;

architecture foo_arch of foo is

signal c : unsigned(1 downto 0) := "00";

begin

   process (CLK)
    begin
        if rising_edge(CLK) then
            c <= c + 1;
            if c = "00" then -- assuming from original code that intent is for A = 00 when c = 01
                A <= "00";
            else
                A <= "ZZ";
            end if;
        end if;
    end process;
    
end foo_arch;

To give:

schematic

simulate this circuit

cjnewby
  • 1
  • 1