我正在尝试根据计数器向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;
谢谢。
答案 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