Vhdl如何重置此信号

时间:2014-01-18 11:22:33

标签: vhdl reset

我正在尝试根据计数器向PC发送两个数据。我只需要发送一次这两个数据,所以我使用的是一个名为“New_data_s”的信号。但我的问题是这个信号保持“高”太多而且数据被发送不止一次。我顺便发送“Datafll_s”。

这是第一次模拟的图片:Sim1

然后我添加了一个名为“Stop_s”的信号来重置这个“New_data_s”。好吧它只发送一次数据,但这一次,我无法重置“Stop_s”。一旦它变为“高”,它就会保持“高”直到我按下按钮。所以我无法发送第二个数据。

这是第二次模拟的图片:Sim2

我知道如果我不按下按钮“ELSIF(Go_s ='1'和Go_s_ff ='0')那么”条件不是TRUE,这就是为什么“Stop_s”保持“高”直到我按下按钮。但是,我找不到办法做到这一点。

反驳部分:

IF(Cnt_Spc_P1>15 and Cnt_Spc_P1<=30)Then
    Three_spc_s<='1';
    Seven_spc_s<='0';
ELSIF(Cnt_Spc_P1>30 and Cnt_Spc_P1<50)Then
    Three_spc_s<='0';
    Seven_spc_s<='1';
ELSIF(Cnt_Spc_P1=50)Then  
    Three_spc_s<='0';
    Seven_spc_s<='1';
    Enable_1_s<='0';
    Cnt_Spc_P1<=0;
ELSE
    Three_spc_s<='0';
    Seven_spc_s<='0';
END IF;

主要部分:

library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.NUMERIC_STD.all;
-------------------------------------------------------------------------------
Entity Letters is
Port(
Clk: in std_logic;
Reset: in std_logic;
Dot: in std_logic;
Dash: in std_logic;
Error : out std_logic;
New_data: out std_logic;
three_spc: in std_logic;
seven_spc: in std_logic;
d_out_d: out std_logic_vector(6 downto 0);
d_out_a: out std_logic_vector(7 downto 0)
);
END Letters;
-------------------------------------------------------------------------------
Architecture Letters_a of Letters is
-------------------------------------------------------------------------------
Type state is (Start, Space, T, E);
Signal current_s: state;
Signal Go_s, Go_s_ff: std_logic:='0';
signal data_d : std_logic_vector(6 downto 0):="1100100";
signal data_a : std_logic_vector(7 downto 0):="00000000";
Signal Error_s, New_data_s : std_logic:='0';
Signal Stop_s : std_logic:='0';
-------------------------------------------------------------------------------
BEGIN
-------------------------------------------------------------------------------
PROCESS(Clk, three_spc, seven_spc, current_s, Reset)
BEGIN
    IF(Reset='1')Then
        current_s<=Start;
        data_d<="0000000";
        data_a<="00000000";
        d_out_d<="1100100";
        Error_s<='0';
        New_data_s<='0';    
        Stop_s<='0';
    ELSIF(Rising_Edge(Clk))Then
        IF(three_spc='1')Then
            d_out_d<=data_d;
            d_out_a<=data_a;
            New_data_s<='1';
            Stop_s<='1';
            current_s<=Start;
        ELSIF(seven_spc='1')Then
            current_s<=Space;
            d_out_d<=data_d;
            d_out_a<="00100000";
            New_data_s<='1';
            Stop_s<='1';
            current_s<=Start;
        ELSIF(Go_s='1' and Go_s_ff='0')Then
            Case current_s is
                When Start =>
                New_data_s<='0';
                Stop_s<='0';
                    IF(Dash='1')Then
                        current_s<=T;
                        data_d<="1100100";
                        data_a<="01010100";
                        Error_s<='0';
                    ELSIF(Dot='1')Then
                        current_s<=E;
                        Error_s<='0';
                        data_d<="0000110";
                        data_a<="01000101";
                    END IF;
------------------------------------------------------------------------------- 
                When T =>                       
                    IF(Dash='1')Then
                        current_s<=M;
                        data_d<="1100100";
                        data_a<="01001101";
                    ELSIF(Dot='1')Then
                        current_s<=N;
                        data_d<="0101011";
                        data_a<="01001110";
                    END IF;
-------------------------------------------------------------------------------             
                When E =>
                    IF(Dash='1')Then
                        current_s<=A;
                        data_d<="0001000";
                        data_a<="01000001";
                    ELSIF(Dot='1')Then
                        current_s<=I;
                        data_d<="1111001";
                        data_a<="01001001";
                    END IF;


                When OTHERS =>
                    current_s <= Start;
                    Error_s<='1'; -- Unidentified letter.
                    data_d<="1100100";
                    New_data_s<='0';
                    Stop_s<='0';
            END Case;
        END IF;

    IF(Stop_s='1')Then
        New_data_s<='0';
    END IF;

    END IF; 
END PROCESS;
-------------------------------------------------------------------------------
PROCESS(Clk, Dot, Dash, Reset)
BEGIN
Go_s<=Dash or Dot;
    IF(Reset='1')Then
        Go_s<='0';
        Go_s_ff<='0';
    ELSIF(Rising_Edge(Clk))Then     
      Go_s_ff<=Go_s;        
   END IF;
END PROCESS;
-------------------------------------------------------------------------------
Error<=Error_s;
New_data<=New_data_s;
-------------------------------------------------------------------------------
END Letters_a;

谢谢。

1 个答案:

答案 0 :(得分:0)

我看到你已经声明了一个枚举类型状态并实例化了一个state状态的信号current_s。枚举类型包括文字(Start,Space,T,E),但是您可以将文字M,N和A分配给不是状态类型成员的信号current_s。您的编译器应该抱怨这一点。是吗?

代码中包含的fsm有点难以理解,因为状态转换代码与输出信号逻辑混合在一起。所以,我重写了它并将其发布在下面。我的fsm可能并不完全代表您正在寻找的功能,但是,您可以将其用作模板。它说明了如何为点和短划线信号生成一个时钟宽边缘检测器。它还说明了如何控制您无法打开和关闭的数据选通信号。

输出逻辑没有充分利用继续输出逻辑case语句的默认信号值,因此您可以更轻松地查看发生的情况。但是,案件中的许多陈述可以通过紧凑来消除。

另外,我还没有编译代码,所以你可能会发现一些语法错误,但模板应该对你有用。

-- Note, not all signals are declared here, refer to the posted code for them

Type state_t is (Idle, start_dot, start_dash, E_dot, strobe_3spc_data,
                    wait_1, strobe_7spc_data, wait_2, E_dash);

signal state_snoop : state_t; -- use to monitor state in simulator
signal dash_ff     : std_logic;
signal dash_pulse  : std_logic;
signal dot_ff      : std_logic;
signal dot_pulse   : std_logic;

fsm: process (clk)
    variable current_s : state_t;
    begin
        if rising_edge(clk) then
            if Reset = '1' then
                current_s := Idle;
            else
                case Idle is
                    when Idle =>
                        if dot_pulse = '1' then
                            current_s := start_dot;
                        elsif dash_pulse = '1' then
                            current_s := start_dash;                       
                        end if;

                    -- dot related states ----------------------        
                    when start_dot =>
                        current_s := E_dot;
                    when E_dot =>
                        if three_spc = '1' then
                            current_s := strobe_3spc_data;
                        end if;                        
                    when strobe_3spc_data =>
                        if seven_spc = '1' then -- counter strobe from external source
                            current_s := wait_1;
                        end if;
                    when wait_1 =>
                        if seven_spc = '1' then -- counter strobe from external source
                            current_s := strobe_7spc_data;
                        end if;
                    when strobe_7spc_data =>
                        current_s := wait_2;
                    when wait_2 =>
                        current_s := idle;

                    -- dash related states ----------------------        
                    when start_dash =>
                        current_s := E_dash;
                    when E_dash =>
                        if three_spc = '1' then
                            current_s := strobe_3spc_data;
                        end if;                        
                end case;
            end if;
        end if;
        state_snoop <= current_s; -- monitor state in simulator. variables are hard to monitor

    --------------   outputs decoded from state variable   -------------------
    -- default signal values
        New_data_s <= '0';
        data_d     <= "0000000";  data_a  <= "00000000";  d_out_d <= "0000000";
        Stop_s     <= '0';        Error_s <= '0';

        case current_s is
            when Idle  =>
                data_d     <= "0000000";
                data_a     <= "00000000";
                d_out_d    <= "1100100";
                Error_s    <= '0';
                New_data_s <= '0';    
            when start_dot  => 
                data_d     <= "0000110"; --'ACK'
                data_a     <= "01000101"; -- ascii dash -> 'E'
                Error_s    <= '0'; 
                New_data_s <= '0';
            when E_dot =>
                data_d <= "1111001";
                data_a <= "01001001";                
            when strobe_3spc_data =>
                d_out_d    <= data_d;
                d_out_a    <= data_a;
                New_data_s <= '1';                
            when wait_1 => -- switch data strobe off for first data transmission
                New_data_s <= '0';
            when strobe_7spc_data =>
                d_out_d    <= data_d;
                d_out_a    <= "00100000";
                New_data_s <= '1';
            when wait_2 => -- switch data strobe off for second data transmission
                New_data_s <= '0';
            -- dash related outputs
            when start_dash  => 
                data_d <= "1100100";  --'t'
                data_a <= "01010100"; --'T'
                Error_s    <= '0'; 
                New_data_s <= '0';
            when E_dash =>
                data_d <= "0001000";
                data_a <= "01000001";
            when others => null;
        end case;


        -- rising edge detector for dash and dot input.
        if Reset = '1' then
            dash_pulse <= '0'
        else
            dash_ff    << not(Dash);
            dash_pulse << dash_ff and dash;
        end if;

        if Reset = '1' then
            dot_pulse <= '0'
        else
            dot_ff    << not(dot);
            dot_pulse << dot_ff and dot;
        end if;

end process fsm