Search code examples
vhdlfpgaxilinx

ERROR: Signal signal_led cannot be synthesized, bad synchronous description


I don't understand why the error:

WARNING:Xst:819 "C:/Users/aa/Desktop/tools/MycourseDesign/control.vhd" line 52: One or more signals are missing in the process sensitivity list. To enable synthesis of FPGA/CPLD hardware, XST will assume that all necessary signals are present in the sensitivity list. Please note that the result of the synthesis may differ from the initial design specification. The missing signals are:
<signal_led>, <signal_q0>, <signal_q1>, <signal_q2>, <signal_q3>, <signal_q4>
ERROR:Xst:827 - "C:/Users/aa/Desktop/tools/MycourseDesign/control.vhd" line 52: Signal signal_led 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.

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL; 
use IEEE.STD_LOGIC_UNSIGNED.ALL;



entity control is
    Port ( clkadd,clksub: in  STD_LOGIC;--脉冲
              --模式
           model : in  STD_LOGIC;
           r : in  STD_LOGIC;--置0端
              --led端输出  3位对应
           led : out  STD_LOGIC_VECTOR (2 downto 0);
              --q0-q4实现5个数码管的BCD码输出
           q0 : out  STD_LOGIC_VECTOR (3 downto 0);
           q1 : out  STD_LOGIC_VECTOR (3 downto 0);
           q2 : out  STD_LOGIC_VECTOR (3 downto 0);
           q3 : out  STD_LOGIC_VECTOR (3 downto 0);
           q4 : out  STD_LOGIC_VECTOR (3 downto 0));


end control;

architecture Behavioral of control is
    --signal 是全局量(只支持逻辑运算)
    --  variable是局部进程变量




    --满位标志
    signal isFull:std_logic_vector(4 downto 0);

    --0位标志
    signal isZero:std_logic_vector(4 downto 0);

    --数码管中继信号
    signal signal_q0,signal_q1,signal_q2,signal_q3,signal_q4:std_logic_vector(3 downto 0);


    --led灯表示选中状态    
    signal signal_led:std_logic_vector(2 downto 0);

begin


    --规定model为0时为移位操作,为1时为调数操作

    --加减数
    p_main:process(clkadd,clksub,r)


    begin
        --清0
        if(r='1')then

            signal_led<="000";  
            signal_q0<="0000";
            signal_q1<="0000";
            signal_q2<="0000";
            signal_q3<="0000";
            signal_q4<="0000";


         --加信号
        elsif(clkadd'event and clkadd='1')then

            --左移模式
            if(model='0')then
                if(signal_led="100")then
                    signal_led<="000";
                else
                    signal_led<=signal_led+1;
                end if;

            --加数模式
            elsif(model='1')then
                    signal_led<=signal_led;
                    if(signal_led="000")then
                            --进位
                            if(signal_q0="1001")then
                                if(isFull="11111")then
                                    signal_q0<=signal_q0;
                                --处理进位
                                else
                                    signal_q0<="0000";
                                    --二次进位
                                    if(signal_q1="1001")then
                                        signal_q1<="0000";
                                        --三次进位
                                        if(signal_q2="1001")then
                                            signal_q2<="0000";
                                            --四次进位
                                            if(signal_q3="1001")then
                                                signal_q3<="0000";
                                                signal_q4<=signal_q4+1;

                                            else
                                            signal_q3<=signal_q3+1;
                                            end if;

                                        else
                                            signal_q2<=signal_q2+1;
                                        end if;

                                    else
                                        signal_q1<=signal_q1+1;
                                    end if;


                                end if;
                            else
                            --加数
                                signal_q0<=signal_q0+1;
                            end if;

                    elsif(signal_led="001")then
                            --进位
                            if(signal_q1="1001")then
                                if(isFull(4 downto 1)="1111")then
                                    signal_q1<=signal_q1;
                                else
                                    signal_q1<="0000";
                                    --处理进位
                                    if(signal_q2="1001")then
                                        signal_q2<="0000";
                                        --二次进位
                                        if(signal_q3="1001")then
                                            signal_q3<="0000";
                                            signal_q4<=signal_q4+1;

                                        else
                                            signal_q3<=signal_q3+1;
                                        end if;

                                    else
                                        signal_q2<=signal_q2+1;
                                    end if;

                                end if;
                            else
                            --加数
                                signal_q1<=signal_q1+1;
                            end if;


                    elsif(signal_led="010")then
                            --进位
                            if(signal_q2="1001")then
                                if(isFull(4 downto 2)="111")then
                                    signal_q2<=signal_q2;
                                else
                                    signal_q2<="0000";
                                    if(signal_q3="1001")then
                                        signal_q3<="0000";
                                        signal_q4<=signal_q4+1;

                                    else
                                        signal_q3<=signal_q3+1;
                                    end if;

                                end if;
                            else
                            --加数
                                signal_q2<=signal_q2+1;
                            end if;


                    elsif(signal_led="011")then
                            --进位
                            if(signal_q3="1001")then
                                if(isFull(4 downto 3)="11") then
                                    signal_q3<=signal_q3;
                                else
                                signal_q3<="0000";
                                signal_q4<=signal_q4+1;

                                end if;
                            else
                            --加数
                                signal_q3<=signal_q3+1;
                            end if;


                    elsif(signal_led="100")then
                            --进位
                            if(signal_q4="0001")then
                                signal_q4<=signal_q4;
                            else
                            --加数
                                signal_q4<=signal_q4+1;
                            end if;

                    end if;


            end if;

            --减信号
        elsif(clksub'event and clksub='1')then
            --右移模式
            if(model='0')then
                if(signal_led="000")then
                    signal_led<="100";
                else
                    signal_led<=signal_led-1;
                end if;



            --减数模式
            elsif(model='1')then
                    signal_led<=signal_led;
                    if(signal_led="000")then
                        if(signal_q0="0000")then
                            if(isZero(4 downto 0)="11111")then
                                signal_q0<=signal_q0;
                            else
                                --借位
                                if(signal_q1="0000")then
                                    signal_q1<="1001";
                                    --二次借位
                                    if(signal_q2="0000")then
                                        signal_q2<="1001";
                                        --三次借位
                                        if(signal_q3="0000")then
                                            signal_q3<="1001";
                                            signal_q4<=signal_q4-1;
                                        else
                                            signal_q3<=signal_q3-1;
                                        end if;

                                    else
                                        signal_q2<=signal_q2-1;
                                    end if;


                                else
                                    signal_q1<=signal_q1-1;
                                end if;

                            end if;
                        else
                            signal_q0<=signal_q0-1;
                        end if;

                    elsif(signal_led="001")then
                        if(signal_q1="0000")then
                            if(isZero(4 downto 1)="1111")then
                                signal_q1<=signal_q1;
                            else
                                --借位
                                if(signal_q2="0000")then
                                    signal_q2<="1001";
                                    --二次借位
                                    if(signal_q3="0000")then
                                        signal_q3<="1001";
                                        signal_q4<=signal_q4-1;

                                    else
                                        signal_q3<=signal_q3-1;
                                    end if;

                                else
                                    signal_q2<=signal_q2-1;
                                end if;

                            end if;

                        else
                            signal_q1<=signal_q1-1;
                        end if;

                    elsif(signal_led="010")then
                        if(signal_q2="0000")then
                            if(isZero(4 downto 2)="111")then
                                signal_q2<=signal_q2;
                            --借位
                            else
                                signal_q2<="1001";
                                if(signal_q3="0000")then
                                    signal_q3<="1001";
                                    signal_q4<=signal_q4-1;

                                else
                                    signal_q3<=signal_q3-1;
                                end if;

                            end if;
                        else
                            signal_q2<=signal_q2-1;
                        end if;

                    elsif(signal_led="011")then
                        if(signal_q3="0000")then
                            if(isZero(4 downto 3)="11")then
                                signal_q3<=signal_q3;
                            else
                                signal_q3<="1001";
                                signal_q4<=signal_q4-1;

                            end if;
                        else
                            signal_q3<=signal_q3-1;
                        end if;


                    elsif(signal_led="100")then
                        if(signal_q4="0000")then
                            signal_q4<=signal_q4;
                        else
                            signal_q4<=signal_q4-1;
                        end if;

                    end if;

            end if;

        end if;



        led<=signal_led;
        q0<=signal_q0;
        q1<=signal_q1;
        q2<=signal_q2;
        q3<=signal_q3;
        q4<=signal_q4;
    end process p_main;



    --数位监控
    level0:process(signal_q0)
        begin
        if(signal_q0="0000")then
            isZero(0)<='1';
        else
            isZero(0)<='0';
        end if;

        if(signal_q0="1001")then
            isFull(0)<='1';
        else
            isFull(0)<='0';
        end if;
    end process level0;


    level1:process(signal_q1)
        begin
        if(signal_q1="0000")then
            isZero(1)<='1';
        else
            isZero(1)<='0';
        end if;

        if(signal_q1="1001")then
            isFull(1)<='1';
        else
            isFull(1)<='0';
        end if;
    end process level1;

    level2:process(signal_q2)
        begin
        if(signal_q2="0000")then
            isZero(2)<='1';
        else
            isZero(2)<='0';
        end if;

        if(signal_q2="1001")then
            isFull(2)<='1';
        else
            isFull(2)<='0';
        end if;
    end process level2;


    level3:process(signal_q3)
        begin
        if(signal_q3="0000")then
            isZero(3)<='1';
        else
            isZero(3)<='0';
        end if;

        if(signal_q3="1001")then
            isFull(3)<='1';
        else
            isFull(3)<='0';
        end if;
    end process level3;


    level4:process(signal_q4)
        begin
        if(signal_q4="0000")then
            isZero(4)<='1';
        else
            isZero(4)<='0';
        end if;

        if(signal_q4="0001")then
            isFull(4)<='1';
        else
            isFull(4)<='0';
        end if;
    end process level4;

end Behavioral;

Solution

  • Your problem boils down to this:

    process (clk_add, clk_sub, r)
    begin
      if (r = '1') then
        -- reset
      elsif (rising_edge(clk_add)) then
        -- assign signal_led
      elsif (rising_edge(clk_sub)) then
        -- assign signal_led
      end if;
    end process;
    

    The basic problem here is that you have signal_led being assigned by edges of two different clocks in one process. There isn't anything in the FPGA that can replicate this; there's no such thing as a dual-clock register in the FPGA, hence this is a 'bad synchronous description'. You need to rewrite your code to use only one clock in each process, but exactly how you would do this depends on what the timing is between clk_add, clk_sub, and the other inputs.

    One example of this might look something like:

    process (clk, r)
    begin
      if (r = '1') then
        -- reset
        some_signal <= 0;
      elsif (rising_edge(clk)) then
        if (add = '1') then
          some_signal <= some_signal + 1;
        elsif (sub = '1') then
          some_signal <= some_signal - 1;
        end if;
      end if;
    end process;
    

    I haven't included all declarations or tried to match the intended function of your code, but hopefully this should give you the right idea.