VHDL State Machine Issue - PullRequest
       43

VHDL State Machine Issue

0 голосов
/ 04 мая 2020

Это конечный автомат, который взаимодействует с другим конечным автоматом, который является главным контроллером SPI. У меня проблемы с тем, что TX_Count работает неправильно. Сигналы TX_Enbl и TX_Continue выводятся на конечный автомат контроллера SPI, а TX_Busy - это флаг занятости от контроллера SPI. Если я установлю NUM_TX_Count на 4, я получу только 2 передачи. Что я делаю неправильно. Благодарю вас.

enter code here
ENTITY SPI_TX_Wr_Fsm IS
    GENERIC(A_width  : INTEGER := 8;                                        -- Width of SPI address
            D_width : INTEGER := 16);                                       -- Data bus width
    PORT (  Reset           : IN STD_LOGIC;                                 -- Reset
            Clk             : IN STD_LOGIC;                                 -- State machine clock
            Write_Init      : IN STD_LOGIC;                                 -- Initiallize the SPI master
            Num_TX_Out      : IN INTEGER;                                   -- Number of TX data transactions
            TX_Busy         : IN STD_LOGIC;                                 -- SPI master controller busy flag
            TX_RegAddr      : IN STD_LOGIC_VECTOR(A_width-1 DOWNTO 0);      -- SPI TX register address
            TX_RegData      : IN STD_LOGIC_VECTOR(D_Width-1 DOWNTO 0);      -- SPI TX register data
            TX_Enbl         : OUT STD_LOGIC;                                -- SPI TX enable
            TX_Data         : OUT STD_LOGIC_VECTOR(A_width+D_width-1 DOWNTO 0);     -- SPI output data (address and data)
            Reset_SPI_n     : OUT STD_LOGIC;                                -- SPI master reset output
            TX_Continue     : OUT STD_LOGIC);                               -- Set for continuous (multiple data) TX
END SPI_TX_Wr_Fsm;

ARCHITECTURE SPI_TX_Wr_Fsm OF SPI_TX_Wr_Fsm IS
TYPE state IS (Reset_SPI_Ctrl, Clr_SPI_Reset, TX_Enable, Clr_TX_Enable, Wait_TX_Done, Idle);
SIGNAL      pr_state, nx_state  : state;
CONSTANT    Count_Max           : INTEGER := 256;
--SIGNAL      TX_Count            : INTEGER;
--SIGNAL      Count_Delay         : INTEGER RANGE 0 TO Count_Max;
--SIGNAL      TX_Continue         : STD_LOGIC;

BEGIN
    -- Sequential section
    PROCESS(Clk, Reset, Write_Init)
    BEGIN
        IF (Reset = '1') OR (Write_Init = '1') THEN
            pr_state <= Reset_SPI_Ctrl;
        ELSIF clk' EVENT AND clk = '1' THEN
            pr_state <= nx_state;
        END IF;
    END PROCESS;
    -- Combinatorial section
    PROCESS (pr_state, TX_Busy)
    VARIABLE  TX_Count  :   INTEGER;
    BEGIN
        Reset_SPI_n <= '1';
        TX_Enbl <= '0';
        TX_Continue <= '0';
        CASE pr_state IS
            WHEN Reset_SPI_Ctrl =>
                Reset_SPI_n <= '0';
                TX_Count := Num_TX_Out;
                IF (TX_Count > 1) THEN
                    TX_Continue <= '1';
                END IF;
                nx_state <= Clr_SPI_Reset;
            WHEN Clr_SPI_Reset =>
                IF (TX_Count > 1) THEN
                    TX_Continue <= '1';
                END IF;
                nx_state <= TX_Enable;
            WHEN TX_Enable =>
                TX_Data <= TX_RegAddr & TX_RegData;
                TX_Enbl <= '1';
                IF (TX_Count > 1) THEN
                    TX_Continue <= '1';
                END IF;
                nx_state <= Clr_TX_Enable;
            WHEN Clr_TX_Enable =>
                IF (TX_Count > 1) THEN
                    TX_Continue <= '1';
                END IF;
                nx_state <= Wait_TX_Done;
            WHEN Wait_TX_Done =>
                IF (TX_Count > 1) THEN
                    TX_Continue <= '1';
                    IF (TX_Busy = '1') THEN
                        nx_state <= Wait_TX_Done;
                    ELSE
                        TX_Count := TX_Count - 1;
                        nx_state <= TX_Enable;
                    END IF;
                ELSE
                    TX_Continue <= '0';
                    nx_state <= Idle;
                END IF;
            WHEN Idle =>
                nx_state <= Idle;
            WHEN OTHERS =>
                nx_state <= Clr_SPI_Reset;
        END CASE;
    END PROCESS;
END SPI_TX_Wr_Fsm;
...