0
votes

I am using the following VHDL to take a 100 Mhz clock and put out a 25 Mhz clock. :

process(clk, reset)
  variable count : integer range 0 to 2;
begin
  if (reset = '1') then
    clock_25MHz <= '0';
    count       := 0;
  elsif rising_edge(clk) then
    count := count+1;
    if(count >= 2) then
      clock_25MHz <= not clock_25MHz;
      count       := 0;
    end if;
  end if;
end process;

It is giving me this warning:

"WARNING:Xst:1293 - FF/Latch count_1 has a constant value of 0 in block . This FF/Latch will be trimmed during the optimization process."

I don't understand why its happening. Can anyone shed some light on this for me? Thanks!

2

2 Answers

0
votes

You don't need 2 bits of count. A single flip flop is enough.

If you add an integer signal CNT that's assigned count (allowing me to see it on a waveform with ghdl):

 library ieee;
 use ieee.std_logic_1164.all;

 entity clk_div is
 end entity;

 architecture foo of clk_div is
     signal clk:            std_logic := '0';
     signal reset:          std_logic := '1';
     signal clock_25MHz:    std_logic;
     signal CNT:            integer;

begin

CLKDIV:
    process(clk,reset)
        variable count: integer range 0 to 2;   
    begin
        if (reset = '1') then
            clock_25MHz <= '0';
            count:=0;
        elsif rising_edge(clk) then
            count:=count+1;
            if(count>=2) then
                clock_25MHz <= not clock_25MHz;
                count:=0;
            end if;
        end if;
        CNT <= count;
      end process;
CLOCK:
    process 
    begin
        wait for 5 ns;
        clk <= not clk;
        if Now > 200 ns then
            wait;
        end if;
    end process;
UNRESET:
    process
    begin
        wait for 20 ns;
        reset <= '0';
        wait;
    end process;
end architecture;

You find:

clock_div with count visible as signal

The count always shows up as either 0 or 1 and not 2 or 3, because you assign it to 0 when ever its 2 or greater. It never shows up as 2 on a clock edge.

Is that correct? Why yes it is. If you clock at the waveform with clock_25MHz lasting 4 100 Mhz clocks it works perfectly. You're process is doing something that's not necessary, count doesn't need a range of 0 to 2, (requiring two flip flops).

Change the evaluation order for count so clock_25MHz is toggled when count = 1, then toggle count. Change the range of count to 0 to 1 or better still make it type std_logic.

     -- signal CNT:            integer;
     signal toggle_ff:      std_logic;

begin

CLKDIV:
    process(clk,reset)
        --variable count: integer range 0 to 2;
        variable toggle:  std_logic;
    begin
        if (reset = '1') then
            clock_25MHz <= '0';
            -- count:=0;
            toggle := '0';
        elsif rising_edge(clk) then
            -- count:=count+1;
            -- if(count>=2) then
            if toggle = '1' then
                clock_25MHz <= not clock_25MHz;
                -- count:=0; 
            end if;
            toggle := not toggle;
        end if;
        -- CNT <= count;
        toggle_ff <= toggle;
      end process;

Which gives:

clock_div with single toggle FF

You could also use a signal in the process statement instead of a variable. In my example code rename toggle_ff to toggle, remove the variable toggle declaration and remove the signal assignment statement to toggle_ff. The reason this will work seamlessly is because you evaluate the output of the toogle FF before it is toggled.

0
votes

The warning occurs since the state in count implemented as FF/Latch by Xilinx goes 0, 1, 0, 1, ..., and only an internal combinatorial value of count ever gets the value 2, thus any bit 1 in the count state will always be 0, as the warning says "FF/Latch count_1 has a constant value of 0 in block".

You can also see this since the code can be rewritten with reduced ´count´ range as 0 to 1, if the count increment is placed inside the if like:

process(clk, reset)
  variable count : integer range 0 to 1;
begin
  if (reset = '1') then
    clock_25MHz <= '0';
    count       := 0;
  elsif rising_edge(clk) then
    if (count = 1) then
      clock_25MHz <= not clock_25MHz;
      count       := 0;
    else
      count := count + 1;
    end if;
  end if;
end process;

But based on the specific requirement of doing a division by 4 from a 100 MHz to a 25 MHz clock, it may be more obvious creating an intermediate 50 MHz clock instead of count, with code like:

process(clk, reset)
  variable clock_50MHz : std_logic;
begin
  if (reset = '1') then
    clock_25MHz <= '0';
    clock_50MHz := '0';
  elsif rising_edge(clk) then
    clock_50MHz := not clock_50MHz;
    if clock_50MHz = '1' then
      clock_25MHz <= not clock_25MHz;
    end if;
  end if;
end process;