-->

VHDL Synthesis - FF/Latch Constant Value

2019-03-03 08:12发布

问题:

I am trying to synthesize a vhdl module I have written.

The code is below:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
use IEEE.NUMERIC_STD.ALL;

entity ClockCounter is
    port(
        clk         : in std_logic;
        input       : in std_logic;
        enable      : in std_logic;
        output      : out std_logic := '0';
        bitReady    : out std_logic := '0';
        countError  : out std_logic := '0'
    );
end ClockCounter;

architecture Behavioral of ClockCounter is

signal totalBitWidth     : integer := 4;
signal majorityValue     : integer := 3;

begin

totalBitWidth <= 4;
majorityValue <= 3;

-- Process for recognizing a single input value from a  clock cycle
-- wide input signal
majority_proc: process(clk, input, enable)

    variable clkCount : integer := 0;
    variable Sum      : integer := 0;

    begin

    if rising_edge(clk) And enable = '1' then
        -- Reset bitReady after one clock cycle
        bitReady <= '0';

        -- Check the input value and add it to the Sum variable
        if input = '1' then
            Sum := Sum + 1;
        else
            Sum := Sum + 0;
        end if;

        -- Increment the clock counter variable
        clkCount := clkCount + 1;

        -- Check if the clock count has reached the specified number of cycles
        if clkCount >= totalBitWidth then
            -- Determine if the Sum variable has met the threshold for
            -- value of 1, set the output accordingly
            if Sum >= majorityValue then
                output <= '1';
            else
                output <= '0';
            end if;

            -- This checks if the value for all clock cycles was the same and
            -- sets an error flag if not
            if Sum = totalBitWidth Or Sum = 0 then
                countError <= '0';
            else
                countError <= '1';
            end if;

            -- Reset the clock counter and sum value
            clkCount := 0;
            Sum := 0;
            -- Set the bit counter high to alert other midules that a new bit
            -- has been received
            bitReady <= '1';
        end if;
        elsif enable = '0' then
        clkCount := 0;
        Sum := 0;
    end if;

    end process;

    end Behavioral;

The problem I am getting is this when trying to synthesize:

WARNING:Xst:1293 - FF/Latch has a constant value of 0 in block . This FF/Latch will be trimmed during the optimization process. WARNING:Xst:1896 - Due to other FF/Latch trimming, FF/Latch has a constant value of 0 in block . This FF/Latch will be trimmed during the optimization process. WARNING:Xst:1896 - Due to other FF/Latch trimming, FF/Latch has a constant value of 0 in block . This FF/Latch will be trimmed during the optimization process.

The trimming goes all the way down to .

What I don't get is that the clkCount variable is an integer that increments up to 6 at most, and then is reset to 0.

Are these warnings something I can ignore?

This module is apart of a larger system I am working on, and when I synthesize the larger system I get a lot of

Found 1-bit latch for signal

So what I am trying to do is eliminate as many warning as possible in lower level modules before fixing the upper level module.

Any help would be great. Thanks

PS - I am using the Xilinx spartan 6 sp605 evaluation kit board, and the Project Navigator.

回答1:

From the looks of it, is is doing what you intended but with optimizations. The clkCount is declared as an integer or 32 bits, but you have it reset to 0 once it hits majority value or 3, which equates to "11" or 2 bits. So therefore clkCount(31 downto 2) will get optimized out since it's always 0.

I would assume that Sum should get optimized down, but the synthesis tool may not notice the coupling that it could get optimized as well.

I'm not a big fan of hard-coded values and you could probably expand this with generics to make it more customizable if you instantiate multiple Clock counters.

library IEEE;
use IEEE.STD_LOGIC_1164.all;

-- Uncomment the following library declaration if using -- arithmetic functions with     Signed or Unsigned values use IEEE.NUMERIC_STD.ALL;
entity ClockCounter is
  generic (
    totalBitWidth : integer := 4;
    majorityValue : integer := 3);
  port(
    clk        : in  std_logic;
    input      : in  std_logic;
    enable     : in  std_logic;
    output     : out std_logic := '0';
    bitReady   : out std_logic := '0';
    countError : out std_logic := '0');
end ClockCounter;

architecture Behavioral of ClockCounter is


begin

-- Process for recognizing a single input value from a clock cycle -- wide input     signal 
  majority_proc : process(clk, input, enable)

    variable clkCount : integer := 0;
    variable Sum      : integer := 0;

  begin

    if rising_edge(clk) and enable = '1' then
                                        -- Reset bitReady after one clock cycle
      bitReady <= '0';
                                        -- Check the input value and add it to the Sum     variable
      if input = '1' then
        Sum := Sum + 1;
      else
        Sum := Sum + 0;
      end if;

                                        -- Increment the clock counter variable
      clkCount := clkCount + 1;

                                        -- Check if the clock count has reached the     specified number of cycles
       if clkCount >= totalBitWidth then
                                        -- Determine if the Sum variable has met the threshold for
                                        -- value of 1, set the output accordingly
        if Sum >= majorityValue then
          output <= '1';
        else
          output <= '0';
        end if;

                                        -- This checks if the value for all clock cycles was the same and
                                        -- sets an error flag if not
        if Sum = totalBitWidth or Sum = 0 then
          countError <= '0';
        else
          countError <= '1';
        end if;

                                        -- Reset the clock counter and sum value
        clkCount := 0;
        Sum      := 0;
                                        -- Set the bit counter high to alert other midules that a new bit
                                        -- has been received
        bitReady <= '1';
      end if;
    elsif enable = '0' then
      clkCount := 0;
      Sum      := 0;
    end if;

  end process;

end Behavioral;


回答2:

It is better to set the expected range of your integers; that way synthesis will generate them the correct size in the first place, rather than 32 bits and then emit hundreds of "trimming" warnings.

Either of

variable clkCount : integer range 0 to totalBitWidth := 0;

can it ever be negative? no? then better...

variable clkCount : natural range 0 to totalBitWidth := 0;
variable Sum      : natural range 0 to majorityValue := 0;

or USE the type system.

For example, if there is a relationship between totalBitWidth and majorityValue, then express it directly instead of making them independent : less to track and get wrong when you change totalBitWidth. (I am guessing at the intended relationship below)

type counttype is new integer range 0 to totalBitWidth;
subtype sumtype is counttype range 0 to totalBitWidth / 2 + 1;

    variable clkCount : counttype := 0;
    variable Sum      : sumtype   := 0;