求助用vhdl写状态机时列出状态的顺序不同为什么会出错?

2019-07-15 21:27发布

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity end_iic is
        port(scl , sda : out std_logic;
                  en : in std_logic;                         --使能
                  output : out std_logic;                    --输出为高时出元
                  reset , clk : in std_logic;
                  to_wait : inout std_logic;
                  en_wait : inout std_logic;
                  to_process : inout std_logic);                  --进入元件时为高
        end end_iic;

architecture Behavioral of end_iic is

        component wait_time is
                port(clk , reset : in std_logic;
                          output : out std_logic;                    --输出为一时出元件
                          en : in std_logic;                         --使能
                          to_process : inout std_logic               --变化时进入外部元件的进程
                          );
        end component;
        type state is(sda_down ,scl_up ,  sda_up , idle);      --顺序不对会出错
        signal pre_state : state;
        signal nex_state : state;
       
        signal a_scl : std_logic;
        signal a_sda : std_logic;
        signal b_scl : std_logic;
        signal b_sda : std_logic;
       
--        signal to_process : std_logic;
--        signal to_wait : std_logic := '1';
--        signal en_wait : std_logic;
        signal out_wait : std_logic;
       
        signal init : std_logic;
--        signal count : integer range 0 to 1;
        signal complete : std_logic;
begin
        scl <= a_scl or (a_scl or b_scl);
        sda <= a_sda or (a_sda or b_sda);
       
        process(reset , clk , en)
        begin
                if(reset = '1') then                       --初始化
                        a_sda <= '1';
                        a_scl <= '1';                           --拉高 时钟线和信号线
                        init <= '0';
                elsif(clk ' event and clk = '1' and en = '1') then
                        if(complete = '1' or init = '0') then                  --初始化 init为0表示第一次进入 complete为0表示已经完成过一次
                                pre_state <= scl_up;                             --初始化pre_state
                                a_scl <= '0';
                                a_sda <= '0';
                                init <= '1';
                        else
                                a_scl <= '0';
                                a_sda <= '0';
                                pre_state <= nex_state;
                        end if;
                end if;
        end process;
       
        process(pre_state , to_process , out_wait)              --定义下一状态
        begin
                case pre_state is
                        when scl_up =>                                --进入元件后的第一个状态
                                b_scl <= '1';                              --拉高时钟线
                                output <= '0';                                                                                 --输出拉低使外部元件可以进入
                                complete <= '0';                                                                         --使下一个时钟上升沿不再初始化
                                if(to_wait /= '0') then                    --初次进入延时使能延时元件  有时间让延时的输出拉低
                                        en_wait <= '1';
                                        to_wait <= '0';
                                        nex_state <= scl_up;
                                elsif(out_wait = '1') then                 --延时元件输出为高 延时结束
                                        nex_state <= sda_down;
                                        to_wait <= '1';
                                else
                                        en_wait <= '0';                         --使能为低此时延时内部使能为高
                                        nex_state <= scl_up;
                                end if;
               
                        when sda_down=>
                                b_sda <= '0';
                                if(to_wait = '1') then
                                        en_wait <= '1';
                                        to_wait <= '0';
                                        nex_state <= sda_down;
                                elsif(out_wait = '1') then
                                        nex_state <= sda_up;
                                        to_wait <= '1';
                                else
                                        en_wait <= '0';
                                        nex_state <= sda_down;
                                end if;
                               
                        when sda_up =>                    --scl拉低状态   
                                b_sda <= '1';
                                if(to_wait = '1') then        --初次进入等待元件
                                        en_wait <= '1';
                                        to_wait <= '0';
                                        nex_state <= sda_up;
                                elsif(out_wait = '1') then         
                                        nex_state <= idle;              --拉低scl
                                        to_wait <= '1';
                                else
                                        en_wait <= '0';
                                        nex_state <= sda_up;                                       
                                end if;
                                               
                        when idle =>
                                nex_state <= idle;
                                output <= '1';
                                complete <= '1';
                end case;
        end process;
       
        u1 : wait_time port map(clk => clk,
                                                                        reset => reset,
                                                                        en => en_wait,
                                                                        output => out_wait,
                                                                        to_process => to_process);
end Behavioral;
这个程序红字部分若把sda_down 放到第二位则波形会出错,不知道是为什么。--注附件为本程序和test beach文件。

end_iic.zip 下载积分: 积分 -1 分
285.13 KB, 下载次数: 4, 下载积分: 积分 -1 分
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。