首页 文章

Vhdl如何重置此信号

提问于
浏览
0

我试图根据计数器向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

    我看到你已经声明了一个枚举类型状态并实例化了一个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
    

相关问题