VHDL 代码中的额外变量赋值使其无法工作并出现错误 "can't infer register" 和 "couldn't implement registers"

Extra variable assignment in VHDL code makes it not work and get error "can't infer register" and "couldn't implement registers"

每当我在我的进程中得到额外的 "i2c_send_flag<='1';" 行时,我都会在下面的代码中遇到错误。

我不明白为什么代码在我添加此行之前有效,而在我添加它之后停止工作。

LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.numeric_std.ALL;

ENTITY MAIN IS
    PORT(
        PIN_CLOCK_50MHZ : IN std_logic;
        PIN_KEY             : IN std_logic_vector (3 downto 0); 
        LEDR                : OUT std_logic_vector (17 downto 0):="000000000000000000";
        LEDG                : OUT std_logic_vector (8 downto 0):="000000000";
        PIN_SW            : IN std_logic_vector (2 downto 0); 
        PIN_I2C_SCLK        : OUT std_logic;
        PIN_I2C_SDA         : INOUT std_logic;
        PIN_MCLK                : OUT std_logic;    
        PIN_BCLK                : OUT std_logic;    
        PIN_ADC_DATA        : IN std_logic; 
        PIN_ADC_LRCK        : OUT std_logic;                                                                                
        PIN_DAC_DATA        : OUT std_logic;    
        PIN_DAC_LRCK        : OUT std_logic                                         
    );
END MAIN;

ARCHITECTURE main OF MAIN IS

    SIGNAL i2c_busy      : std_logic;
    SIGNAL i2c_send_flag : std_logic;
    SIGNAL i2c_data      : std_logic_vector(15 downto 0);
    SIGNAL i2c_done     : std_logic;
    SIGNAL clock_12mhz      : std_logic;
    SIGNAL clock_2m4hz          : std_logic;
    SIGNAL clock_100hz      : std_logic;
    SIGNAL clock_6mhz           : std_logic;
    SIGNAL adc_dac_bclk     : std_logic;
    SIGNAL adc_data         : std_logic;
    SIGNAL adc_lrck         : std_logic;
    SIGNAL dac_data         : std_logic;
    SIGNAL dac_lrck         : std_logic;

    COMPONENT i2c IS
        PORT(
            I2C_CLOCK_12MHZ: IN std_logic                               :='0';
            I2C_DEVICE_ADDR: IN std_logic_vector (7 downto 0)   :="00000000";
            I2C_DATA            : IN std_logic_vector (15 downto 0) :="0000000000000000";

            I2C_START_FLAG  : IN std_logic                              :='0';
            I2C_BUSY            : OUT std_logic                         :='0';
            I2C_DONE            : OUT std_logic                         :='0';

            I2C_SCLK            : OUT std_logic                         :='1';
            I2C_SDA         : INOUT std_logic                           :='1'
        );
    END COMPONENT i2c;

    COMPONENT pll IS
        PORT (
            inclk0  : IN STD_LOGIC  := '0';
            c0          : OUT STD_LOGIC 
        );
    END COMPONENT pll;

    COMPONENT divclk_12M_2M4 IS
        PORT (
            clk_in   : IN std_logic;
            clk_out  : OUT std_logic
        );
    END COMPONENT divclk_12M_2M4;

    COMPONENT divclk_12M_100 IS
        PORT (
            clk_in   : IN std_logic;
            clk_out  : OUT std_logic
        );
    END COMPONENT divclk_12M_100;

    COMPONENT divclk_12M_6M IS
        PORT (
            clk_in   : IN std_logic;
            clk_out  : OUT std_logic
        );
    END COMPONENT divclk_12M_6M;    

    COMPONENT adc_dac_controller IS
        PORT(
            CTRL_BCLK       :  IN std_logic;

            CTRL_ADC_DATA   :  IN  std_logic;
            CTRL_ADC_LRCK   :  OUT std_logic;

            CTRL_DAC_DATA   :  OUT std_logic;
            CTRL_DAC_LRCK   :  OUT std_logic
        );
    END COMPONENT adc_dac_controller;

    BEGIN

            WM8731: COMPONENT i2c 
                            PORT MAP(
                                I2C_CLOCK_12MHZ=>   clock_12mhz,
                                I2C_DEVICE_ADDR=>   "00110100",
                                I2C_DATA            =>  i2c_data,

                                I2C_START_FLAG  =>  i2c_send_flag,
                                I2C_BUSY            =>  i2c_busy,

                                I2C_DONE            =>  i2c_done,

                                I2C_SCLK            =>  PIN_I2C_SCLK,
                                I2C_SDA         =>  PIN_I2C_SDA 
                            );  
            PLL12:  COMPONENT pll 
                            PORT MAP(
                                inclk0          =>  PIN_CLOCK_50MHZ,
                                c0                  =>  clock_12mhz 
                            );

            Divclk_2M4Hz:   COMPONENT divclk_12M_2M4 
                                    PORT MAP(
                                        clk_in  =>  clock_12mhz,
                                        clk_out =>  clock_2m4hz
                                    );                                              
            Divclk_6MHz:    COMPONENT divclk_12M_6M 
                                    PORT MAP(
                                        clk_in  =>  clock_12mhz,
                                        clk_out =>  clock_6mhz
                                    );                              
            Divclk_100Hz:   COMPONENT divclk_12M_100 
                                    PORT MAP(
                                        clk_in  =>  clock_12mhz,
                                        clk_out =>  clock_100hz
                                    );                                              

            adc_dac_ctrl:   COMPONENT adc_dac_controller
                                    PORT MAP(

                                        CTRL_BCLK       => clock_12mhz,


                                        CTRL_ADC_DATA   => adc_data,
                                        CTRL_ADC_LRCK   => adc_lrck,

                                        CTRL_DAC_DATA   => dac_data,
                                        CTRL_DAC_LRCK   => dac_lrck
                                    );                                  


    PIN_MCLK        <= clock_12mhz;
    PIN_BCLK        <= clock_12mhz;
    adc_data        <= PIN_ADC_DATA;
    PIN_ADC_LRCK<= adc_lrck;
    PIN_DAC_DATA<= dac_data;
    PIN_DAC_LRCK<= dac_lrck;
    LEDG(7)     <= i2c_done;

    PROCESS (clock_100hz)
    BEGIN

        IF rising_edge (clock_100hz) THEN
            IF (PIN_KEY="1111") THEN
                 i2c_send_flag <='0';
            END IF;
        END IF;

        IF rising_edge(clock_100hz) AND i2c_busy='0' THEN

            IF (PIN_SW (0)='1' AND PIN_KEY(0)='0') THEN                             
                        i2c_data(15 downto 9)<="0000000";
                        i2c_data(8)<='0'; 
                        i2c_data(7)<='0';
                        i2c_data(6 downto 5)<="00";
                        i2c_data(4 downto 0)<="11111";
                        i2c_send_flag<='1'; 
                    ------------------------------------------------------
            ELSIF (PIN_SW (0)='1' AND PIN_KEY(1)='0') THEN
                        i2c_data(15 downto 9)<="0000001";
                        i2c_data(8)<='1';
                        i2c_data(7)<='0';
                        i2c_data(4 downto 0)<="11111";
                        i2c_send_flag<='1';
                    ------------------------------------------------------
            ELSIF (PIN_SW (0)='1' AND PIN_KEY(2)='0') THEN      
                        i2c_data(15 downto 9)<="0000010";
                        i2c_data(8)<='0';
                        i2c_data(7)<='1';
                        i2c_data(6 downto 0)<="1111000";
                        i2c_send_flag<='1';
            ELSIF (PIN_SW (0)='1' AND PIN_KEY(3)='0') THEN
                        i2c_data(15 downto 9)<="0000011";
                        i2c_data(8)<='1';
                        i2c_data(7)<='1'; 
                        i2c_data(6 downto 0)<="1111000";
                        i2c_send_flag<='1';             
            ELSIF (PIN_SW (1)='1' AND PIN_KEY(0)='0') THEN
                        i2c_data(15 downto 9)<="0000100";
                        i2c_data(8)<='0';                       
                        i2c_data(7 downto 6)<="11";
                        i2c_data(5)<='0'; 
                        i2c_data(4)<='1'; 
                        i2c_data(3)<='0';
                        i2c_data(2)<='0';
                        i2c_data(1)<='1';
                        i2c_data(0)<='0';
                        i2c_send_flag<='1';
            ELSIF (PIN_SW (1)='1' AND PIN_KEY(1)='0') THEN
                        i2c_data(15 downto 9)<="0000101";
                        i2c_data(8 downto 5)<="0000";   
                        i2c_data(4)<='0'; 
                        i2c_data(3)<='0'; 
                        i2c_data(2 downto 1)<="11";
                        i2c_data(0)<='0'; 
                        i2c_send_flag<='1';                             
            ELSIF (PIN_SW (1)='1' AND PIN_KEY(2)='0') THEN
                        i2c_data(15 downto 9)<="0000110";
                        i2c_data(8)<='0';
                        i2c_data(7)<='0';
                        i2c_data(6)<='1';
                        i2c_data(5)<='1';
                        i2c_data(4)<='0';
                        i2c_data(3)<='0';
                        i2c_data(2)<='0'; 
                        i2c_data(1)<='1'; 
                        i2c_data(0)<='0';
                        i2c_send_flag<='1';                             
            ELSIF (PIN_SW (1)='1' AND PIN_KEY(3)='0') THEN
                        i2c_data(15 downto 9)<="0000111";
                        i2c_data(8)<='0';
                        i2c_data(7)<='0';
                        i2c_data(6)<='0';
                        i2c_data(5)<='0';
                        i2c_data(4)<='1';
                        i2c_data(3 downto 2)<="00";
                        i2c_data(1 downto 0)<="10";
                        i2c_send_flag<='1';                         
            ELSIF (PIN_SW (2)='1' AND PIN_KEY(0)='0') THEN
                        i2c_data(15 downto 9)<="0001000";
                        i2c_data(8)<='0';
                        i2c_data(7)<='0';
                        i2c_data(6)<='0';
                        i2c_data(5 downto 2)<="0000";
                        i2c_data(1)<='0'; 
                        i2c_data(0)<='1';
                        i2c_send_flag<='1';                         
            ELSIF (PIN_SW (2)='1' AND PIN_KEY(1)='0') THEN
                        i2c_data(15 downto 9)<="0001001"; 
                        i2c_data(8 downto 1)<="00000000";
                        i2c_data(0)<='1';
                        i2c_send_flag<='1';         
--          ELSIF (PIN_SW (2)='1' AND PIN_KEY(3)='0') THEN
--                      i2c_data(15 downto 9)<="0001111";
--                      i2c_data(8 downto 0)<="000000000";
--                      i2c_data(15 downto 0)<="0001111000000000";
--                      i2c_send_flag<='1';
            END IF;

        END IF;
    END PROCESS;

END main;

当我取消注释 If 语句中代码的最后一部分时,出现以下错误:

我无法理解为什么当我再次添加这段代码(我在下面的 "Elsif" 中使用它并起作用)时它会失败。

一般来说,为了让综合工具满意,每个进程需要一个时钟,并且时钟语句中没有逻辑。应用于您的代码,需要将其重组为:

PROCESS (clock_100hz)
BEGIN

    IF rising_edge (clock_100hz) THEN
        IF (PIN_KEY="1111") THEN
             i2c_send_flag <='0';
        END IF;
        if i2c_busy='0' THEN

          IF (PIN_SW (0)='1' AND PIN_KEY(0)='0') THEN                             
                    i2c_data(15 downto 9)<="0000000";
                    i2c_data(8)<='0'; 
                    i2c_data(7)<='0';
                    i2c_data(6 downto 5)<="00";
                    i2c_data(4 downto 0)<="11111";
                    i2c_send_flag<='1'; 
                ------------------------------------------------------
          ELSIF (PIN_SW (0)='1' AND PIN_KEY(1)='0') THEN
                    i2c_data(15 downto 9)<="0000001";
                    i2c_data(8)<='1';
                    i2c_data(7)<='0';
                    i2c_data(4 downto 0)<="11111";
                    i2c_send_flag<='1';
          ELSIF ...
                ...
          END IF;
        END IF;
      END IF;