Clock problem with Spartan 6

Generally speaking you should not be writing dividers like this. You are creating a clock signal out of logic, which as ISE is telling you, is not a recommended design practise. Not only are you consuming (often scarce) clock routing nets, but you can also end up with jittery, glitchy clocks as the logic blocks ripple through to their next state.

examples (in VHDL, I prefer it to Verilog, but it's a simple enough example)

e.g. 1: how NOT to do it (create a clock from logic outputs):

signal counter: integer range 0 to 999;
signal slowclk: std_logic;

gen_slowclk: process(clk, rst)
begin
    if rising_edge(clk) then
        if counter = 0 then
            slow_clk <= not slow_clk;
            counter <= counter'high
        else
            counter <= counter - 1;
        end if;
    end if;

    if rst = '1' then
        slow_clk <= '0';
        counter = counter'high;
    end if;
end process;

use_slow_clk: process(slow_clk, rst)
begin
    if rising_edge(slow_clk) then
        -- ...
    end if;

    if reset = '1' then
        -- ...
    end if;
end process;

This creates a slow_clk which is 1000 times slower than the main clock, and then uses that slow_clk signal as the clock input in another process. It's an example of how not to do things. If you examine your RTL you'll see the output of logic going into the clock inputs of the FFs in the use_slow_clk process, which is bad.

What you should be doing instead is creating clock enables. You drive all your logic with the original (fast) clock, and then create a clock enable signal. Most FPGAs have flip-flop primitives that have clock enable inputs, which is exactly why you would design this way.

e.g. 2: Use clock enables (the recommended way):

signal counter: integer range 0 to 999;
signal slow_ce: std_logic;

gen_slow_ce: process(clk, rst)
begin
    if rising_edge(clk) then
        if counter = 0 then
            slow_ce <= '1';
            counter <= counter'high
        else
            slow_ce <= '0';
            counter <= counter - 1;
        end if;
    end if;

    if rst = '1' then
        slow_ce <= '0';
        counter = counter'high;
    end if;
end process;

use_slow_ce: process(clk, rst)
begin
    if rising_edge(clk) then
        if slow_ce = '1' then
            -- ...
        end if;
    end if;

    if reset = '1' then
        -- ...
    end if;
end process;

If you examine the RTL of this type of construction, you will see that all FFs use the same clock signal, and that is provided on a clock net. The added @if slow_ce = '1'@ is recognized by the synthesizer and instantiates an FF with a clock enable; this is a signal which is designed to be controlled with logic and to cleanly gate the FF.

In both of these examples, the logic in @use_slow_*@ is executed at the same frequency (1/1000 the main clock) but in the second case you have only one clock network and are making use of the clock enables present in your FPGA, which leads to better synthesis, better clocks and easier timing closure. This leads to saner FPGA designs which leads to happy FPGA designers. :-)


Your clk pin is driving some non-clock pins (LUT inputs by the look of it). This is almost always a bad idea.

Open your design in the technology viewer and look at the "non-clock load pins" listed in the logfile (< PIN: sync_apbinterface_0/pclk_test_select[15]_AND_253_o4.A4; > is the first one) and see if you can figure out why a LUT is using the CLK input.

If it turns out that all is OK and you really want to do this, for whatever reason, and you are going to be happy justifying that to a baying pack of engineers if it all goes wrong, you can turn the error off as described at the end of the error message.


Perhaps there's a problem with the two simultaneous assignments to counter. See if changing your always block to this helps:

  always @(posedge clk) begin
    if(counter == SYNC_OUT_CLOCK_RATIO) begin
      counter <= 0;
      sync <= ~sync;
    end else begin
      counter <= counter + 1;
    end
  end

Tags:

Verilog