我试图根据计数器向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 回答
我看到你已经声明了一个枚举类型状态并实例化了一个state状态的信号current_s . 枚举类型包括文字(Start,Space,T,E),但是您可以将文字M,N和A分配给不是状态类型成员的信号current_s . 您的编译器应该抱怨这一点 . 可以?
代码中包含的fsm有点难以理解,因为状态转换代码与输出信号逻辑混合在一起 . 所以,我重写了它并将其发布在下面 . 我的fsm可能并不完全代表您正在寻找的功能,但是,您可以将其用作模板 . 它说明了如何为点和短划线信号生成一个时钟宽边缘检测器 . 它还说明了如何控制您无法打开和关闭的数据选通信号 .
输出逻辑没有充分利用继续输出逻辑case语句的默认信号值,因此您可以更轻松地查看发生的情况 . 但是,为了紧凑,可以消除案件中的许多陈述 .
此外,我还没有编译代码,所以你可能会发现一些语法错误,但模板应该对你有用 .