编译时提示产生了lacth请问怎么解决?

2019-07-15 23:21发布

写了一个小程序,仿真可以通过但烧到板子上运行不正常,看了一下编译过程发现CW和NCW两个信号产生了LATCH,请问有知道是为什么的吗?如何解决呢?
代码如下:
--*****************************************************
-- Filename      :   
-- Author        :
-- Description   :
-- Callde by         :  
-- Revision      : R1.0
-- Date          :   
--*****************************************************

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all ;
use IEEE.std_logic_unsigned.all ;

entity encoder is
        port (
--------------ROTARY INPUT        --------------               
                        PI_A        : in std_logic;
                        PI_B        : in std_logic;
                        RESET       : in std_logic;
                        CLK         : in std_logic;
--------------SWITCH CONTROL--------------                       
                        PO_CW          : out std_logic :='0';     --CW FOR CLOCKWISE;
                        PO_NCW         : out std_logic :='0'      --nCW FOR ANTICLOCKWISE;
                       
                        );
end encoder;

architecture behav of encoder is

--------------SIGNAL DEFINE--------------
type state_type is (s00,s01,s10,s11);
signal PR_STATE, NT_STATE  :state_type;
signal CW,NCW       :std_logic;
signal CLK_CNT1     : std_logic_vector(15 downto 0) :="0000000000000001";
signal CLK_CNT2     : std_logic_vector(15 downto 0) :="0000000000000001";

begin

process(CLK,RESET)
begin
        if(RESET = '1') then
                PR_STATE <= s00;
        else
                if(CLK'event and CLK='1') then
                        PR_STATE <= NT_STATE;
                end if;
        end if;
end process;

process(PI_A,PI_B,PR_STATE)
begin

        case PR_STATE is
                when s00 =>
                        if(PI_A='1' and PI_B='0') then
                                NT_STATE <= s10;
                                CW <='1';
                        elsif(PI_A='0' and PI_B='1') then
                                NT_STATE <= s01;
                                NCW <= '1';               
                        else
                                NT_STATE <= s00;
                                CW <= '0';
                                NCW <= '0';
                        end if;
                when s10 =>
                        if(PI_A='0' and PI_B='0') then
                                NT_STATE <= s00;
                                NCW <='1';
                        elsif(PI_A='1' and PI_B='1') then
                                NT_STATE <= s11;
                                CW <= '1';
                        else
                                NT_STATE <= s10;
                                CW <= '0';
                                NCW <= '0';                               
                        end if;
                when s11 =>
                        if(PI_A='1' and PI_B='0') then
                                NT_STATE <= s10;
                                NCW <='1';
                        elsif(PI_A='0' and PI_B='1') then
                                NT_STATE <= s01;
                                CW <= '1';
                        else
                                NT_STATE <= s11;
                                CW <= '0';
                                NCW <= '0';
                        end if;
                when s01 =>
                        if(PI_A='0' and PI_B='0') then
                                NT_STATE <= s00;
                                CW <='1';
                        elsif(PI_A='1' and PI_B='1') then
                                NT_STATE <= s11;
                                NCW <= '1';
                        else
                                NT_STATE <= s01;
                                CW <= '0';
                                NCW <= '0';
                        end if;
                end case;
               
end process;

process(CLK,CW,NCW)
begin
                if (CLK'event and CLK ='1') then
                                if (CLK_CNT1 = "1111111111111111") then
                                        CLK_CNT1 <= (others => '0');
                                        PO_CW <= '0';
                                else
                                        CLK_CNT1 <= CLK_CNT1+1;
                                end if;
                end if;
               
                if ( CW = '1') then
                        CLK_CNT1 <= "0000000000000000";
                        PO_CW <= '1';
                end if;
       

                if (CLK'event and CLK ='1') then
                        if (CLK_CNT2 = "1111111111111111") then
                                CLK_CNT2 <= (others => '0');
                                PO_NCW <= '0';
                        else
                                CLK_CNT2 <= CLK_CNT2+1;
                        end if;
                end if;
                if (NCW = '1') then
                        CLK_CNT2 <= "0000000000000000";
                        PO_NCW <= '1';
                end if;

end process;
       
end behav;

友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
7条回答
elecfans跑堂
1楼-- · 2019-07-15 23:34
 精彩回答 2  元偷偷看……
caojianxun
2楼-- · 2019-07-16 05:05
你的最后一个进程里if(cw=1)和if(ncw=1)两个if没有在时钟里,我感觉这个进程可以更改。还有你应该对你的功能稍微描述下,没有太搞懂你的基本功能。
caojianxun
3楼-- · 2019-07-16 09:15
将你的case语句中cw和ncw的语句补全。
-- LATCH.vhd
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all ;
use IEEE.std_logic_unsigned.all ;

entity encoder is
        port (
--------------ROTARY INPUT        --------------               
                        PI_A        : in std_logic;
                        PI_B        : in std_logic;
                        RESET       : in std_logic;
                        CLK         : in std_logic;
--------------SWITCH CONTROL--------------                        
                        PO_CW          : out std_logic :='0';     --CW FOR CLOCKWISE;
                        PO_NCW         : out std_logic :='0'      --nCW FOR ANTICLOCKWISE;
                        
                        );
end encoder;

architecture behav of encoder is

--------------SIGNAL DEFINE--------------
type state_type is (s00,s01,s10,s11);
signal PR_STATE, NT_STATE  :state_type;
signal CW,NCW       :std_logic;
signal CLK_CNT1     : std_logic_vector(15 downto 0) :="0000000000000001";
signal CLK_CNT2     : std_logic_vector(15 downto 0) :="0000000000000001";

begin

process(CLK,RESET)
begin
        if(RESET = '1') then
                PR_STATE <= s00;
        else
                if(CLK'event and CLK='1') then
                        PR_STATE <= NT_STATE;
                end if;
        end if;
end process;

process(PI_A,PI_B,PR_STATE)
begin

        case PR_STATE is
                when s00 =>
                        if(PI_A='1' and PI_B='0') then
                                NT_STATE <= s10;
                                CW <='1';
                                ncw<='0';
                        elsif(PI_A='0' and PI_B='1') then
                                NT_STATE <= s01;
                                cw<='0';
                                NCW <= '1';               
                        else
                                NT_STATE <= s00;
                                CW <= '0';
                                NCW <= '0';
                        end if;
                when s10 =>
                        if(PI_A='0' and PI_B='0') then
                                NT_STATE <= s00;
                                cw<='0';
                                NCW <='1';
                        elsif(PI_A='1' and PI_B='1') then
                                NT_STATE <= s11;
                                CW <= '1';
                                ncw<='0';
                        else
                                NT_STATE <= s10;
                                CW <= '0';
                                NCW <= '0';                                
                        end if;
                when s11 =>
                        if(PI_A='1' and PI_B='0') then
                                NT_STATE <= s10;
                                NCW <='1';
                                cw<='0';
                        elsif(PI_A='0' and PI_B='1') then
                                NT_STATE <= s01;
                                CW <= '1';
                                ncw<='0';
                        else
                                NT_STATE <= s11;
                                CW <= '0';
                                NCW <= '0';
                        end if;
                when s01 =>
                        if(PI_A='0' and PI_B='0') then
                                NT_STATE <= s00;
                                CW <='1';
                                ncw<='0';
                        elsif(PI_A='1' and PI_B='1') then
                                NT_STATE <= s11;
                                NCW <= '1';
                                cw<='0';
                        else
                                NT_STATE <= s01;
                                CW <= '0';
                                NCW <= '0';
                        end if;
               
                end case;
               
end process;

process(CLK,CW,NCW)
begin
                if (CLK'event and CLK ='1') then
                                if (CLK_CNT1 = "1111111111111111") then
                                        CLK_CNT1 <= (others => '0');
                                        PO_CW <= '0';
                                else
                                        CLK_CNT1 <= CLK_CNT1+1;
                                end if;
                end if;
               
                if ( CW = '1') then
                        CLK_CNT1 <= "0000000000000000";
                        PO_CW <= '1';
                end if;
        

                if (CLK'event and CLK ='1') then
                        if (CLK_CNT2 = "1111111111111111") then
                                CLK_CNT2 <= (others => '0');
                                PO_NCW <= '0';
                        else
                                CLK_CNT2 <= CLK_CNT2+1;
                        end if;
                end if;
                if (NCW = '1') then
                        CLK_CNT2 <= "0000000000000000";
                        PO_NCW <= '1';
                end if;

end process;
        
end behav;
就可以了。
yuggdra
4楼-- · 2019-07-16 15:00
caojianxun 发表于 2015-11-6 21:10
将你的case语句中cw和ncw的语句补全。
-- LATCH.vhd
library IEEE;

学习了很多,谢谢
yuggdra
5楼-- · 2019-07-16 18:00
发完帖子就找到了解决办法,在case语句之前分别给cw和ncw赋值为0就可以了,
yuggdra
6楼-- · 2019-07-16 18:56
 精彩回答 2  元偷偷看……

一周热门 更多>