Search code examples
if-statementvhdlfpga

Where does the error stem from in the process?


library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.all;


entity reset40 is
Port (  CLOCK : in  STD_LOGIC;  --50MHz
        CIKIS : out STD_LOGIC


        );

end reset40;

architecture Behavioral of reset40 is

    signal A:std_logic;
begin

    process(CLOCK)  --line20

        variable fcounter: unsigned(24 downto 0);
        variable counter_A:integer range 0 to 40:=0;

    begin

        if rising_edge (CLOCK) then   
            fcounter := fcounter+1;         
        end if;

        A<=fcounter(6);           --fa=fclock/2^6

        if ((rising_edge (A)) and (counter_A/=40)) then  
            counter_A:= counter_A+1;              
            CIKIS<=A;
        else
            CIKIS<='0';
        end if;

    end process;
end Behavioral;

ERROR:Xst:827 - "C:/Users/reset40/reset40.vhd" line 20: Signal CIKIS cannot be synthesized, bad synchronous description. The description style you are using to describe a synchronous element (register, memory, etc.) is not supported in the current software release.

What is the error about clock? How come is it a 'bad synchronous description'?


Solution

  • Your basic mistake is that all the code that is in the process needs to run only on the rising edge of the clock. This is because the target chip only has flipflops which can respond on one edge.

    The process you have written is sensitive to changes in clock due to this line:

    process(clock)
    

    so it is sensitive to both clock edges.

    You have then put part of the code inside an

    if rising_edge(clock) then
    

    which limits activity to just the rising edge, which is good. The rest of your code is unfortunately outside of that if clause, and so is described as operating on every edge of the clock, either rising or falling. In simulation this will be fine, but the synthesiser cannot find any flipflops which can do that, hence the error.

    Other things to note - you need to reset or initialise your counter somehow. Either with a reset signal, so that any time the reset signal is high, the counter is set back to all zeros. Or using an initialisation statement.

    You can get away without them for pure synthesis, as the sythesiser will (in the absence of init or reset code) automatically set the counter to all zeros when the FPGA starts up. It's poor-form though as:

    • it won't work in simulation and simulation is vital. You may not have realised this yet, but you will eventually!
    • if you port the code to another architecture which cannot magically initialise things, you wil get random 1s and 0s in the counter at startup. This may or may not matter, but it's best to avoid having to decide.