VHDL - “Input is never used warning”

2019-07-08 09:20发布

问题:

I've written a program in VHDL (for Xilinx Spartan-6) that increments a counter whilst a button is pressed and resets it to zero when another button is pressed.

However, my process throws the error WARNING:Xst:647 - Input is never used. This port will be preserved and left unconnected... for the reset variables - despite the fact that it is used both in the sensitivity of the process and as a condition (just as much as button, yet that doesn't get flagged!).

binary_proc : process(CLK_1Hz, button, reset) --include all inputs on sensitivity list
begin
    if rising_edge(CLK_1Hz) and button = '1' then
        binary <= binary + 1;
    else if reset = '1' then
            binary <= (others => '0');
        end if;
    end if;
end process;

More curiously though, I can fix this by simply using two if statements rather than just an if-else if statement, as shown below;

binary_proc : process(CLK_1Hz, button, reset) --include all inputs on sensitivity list
begin
    if rising_edge(CLK_1Hz) and button = '1' then
        binary <= binary + 1;
    end if;
    if reset = '1' then
        binary <= (others => '0');
    end if;
end process;

My question is: why is the reset variable optimized out of the circuit when an if-else statement is used but not when two if statements are used? What causes this and how can this sort of thing be avoided it?

Thanks very much!

NB: Full code of the program is below in case it helps!

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity button_press is
    port(
        CLK_200MHz : in  std_logic;
        button     : in  std_logic;
        reset      : in  std_logic;
        LED        : out std_logic_vector(3 downto 0) --array of LED's
    );

end button_press;

architecture Behavioral of button_press is
    signal CLK_1Hz : std_logic;         --input clock (think 200 MHz)
    signal counter : std_logic_vector(26 downto 0); --counter to turn 200 MHz clock to 1 Hz
    signal binary  : std_logic_vector(3 downto 0); --binary vector thats mapped to LED's
begin
    -----Create 1 Hz clock signal from 200 MHz system clock-------
    prescaler : process(CLK_200MHz)
    begin
        if rising_edge(CLK_200MHz) then
            if (counter < 2500000) then --possibly change to number in binary
                counter <= counter + 1;
            else
                CLK_1Hz <= not CLK_1Hz; --toggle 1 Hz clock
                counter <= (others => '0'); --reset counter to 0
            end if;
        end if;
    end process;
    ------ Increment binary number when on rising clock edge when button pressed -------
    binary_proc : process(CLK_1Hz, button, reset) --include all inputs on sensitivity list
    begin
        if rising_edge(CLK_1Hz) and button = '1' then
            binary <= binary + 1;
        end if;
        if reset = '1' then
            binary <= (others => '0');
        end if;
    end process;

    LED <= binary;                      --map binary number to LED's

end Behavioral;

回答1:

The problem is, that reset is conditional to not (rising_edge(CLK_1Hz) and button = '1'), and the Xilinx XST tool can't figure out how to map this to FPGA hardware.

VHDL is a Hardware Description Language (HDL part of VHDL), so don't think of it like writing another program (e.g. as in C or Python), but think of it as describing a circuit.

Converting VHDL code to hardware is a complicated task, and Xilinx expects the designer to use some patterns, as described in the "XST Hardware Description Language (HDL) Coding Techniques" of the Xilinx XST User Guide. The first code part does not follow any of these patterns, and XST fails to convert this to hardware, thus the warning.

As per that coding style, the way to write it would be:

process(CLK_1Hz, reset) is  -- Don't include button, since sync. signal
begin
  if reset = '1' then
    binary <= (others => '0');
  elsif rising_edge(CLK_1Hz) then
    if button = '1' then
      binary <= binary + 1;
    end if;
  end if;
end process;

Btw. consider not making an extra clock as CLK_1Hz, but make an increment enable signal instead, since every clock requires special handling and resources.