在 Spartan 3E 上实现由按钮触发的短脉冲信号
Implementing a short pulse signal triggered by a push button on a Spartan 3E
我正在尝试在交通灯控制器上实现 "emergency" 功能。
此紧急信号是一个 std_logic 输入,由按钮触发(使用 ucf 文件)。
这个信号的作用基本上是只要按下按钮,控制器就会检测到两条路(从北到南或从西到东)中的哪条路是红色的,它会立即将其切换为橙色(另一个当然会变成红色)让紧急车辆通过(例如救护车)。
我试过检测开关,然后将检测信号馈入上升沿检测器。它没有用:按下紧急按钮使两条路(NS 和 WE)的红灯和黄灯同时亮起,简直是一场灾难,我用来配置每盏灯亮多长时间的计数器也受到干扰好一阵子才恢复正常。
到目前为止,这是我的代码:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.std_logic_unsigned.all;
use ieee.numeric_std.all;
entity TLC is
Port (
Clck : in STD_LOGIC;
Reset: in STD_LOGIC;
emergency:in std_logic;
Trafficlights: out STD_LOGIC_Vector (5 downto 0) --trafficlights (5 downto 3) for the NS road and (2 downto 0) for the WE road.
);
end TLC;
architecture Behavioral of TLC is
-------------for debouncing
constant COUNT_MAX : integer := 20;
constant BTN_ACTIVE : std_logic := '1';
signal count1 : integer := 0;
type state_type1 is (idle,wait_time);
signal state1 : state_type1 := idle;
signal emergency_debounced:std_logic;
-----------------------------------------
type state_type is (NRWG, NRWY, NGWR, NYWR); --NRWG: North-South on red and West-East on green and so on.
signal one_second_counter: STD_LOGIC_vector(25 downto 0):="00000000000000000000000000";
signal one_second_enable: std_logic;
signal state: state_type:=NRWG;
signal count : std_logic_vector (3 downto 0);
constant sec8 : std_logic_vector ( 3 downto 0) := "1000";
constant sec3 : std_logic_vector (3 downto 0 ) := "0011";
constant sec11: std_logic_vector (3 downto 0 ) := "1011";
--edge detector signals
signal emergencya, emergencyb, emergencyc: std_logic;
----------
begin
controller: process (Clck,reset,emergencyc)
begin
if emergencyc='1' then
if state=NRWG or state=NRWY then ----if NS is on red then switch it to yellow.
state<=NYWR;
count<=x"0";
else
if state=NGWR or state=NYWR then ----if WE is on red then switch it to yellow.
state<=NRWY;
count<=x"0";
end if;
end if;
elsif reset ='1' then
state<=NRWG;
count<=X"0";
else
if rising_edge(clck) then
if one_second_enable='1' then
case state is
when NRWG =>
if count < sec8 then
state <= NRWG;
count <= count + 1;
else
state <= NRWY;
count <= X"0";
end if;
when NRWY =>
if count < sec3 then
state <= NRWY;
count <= count + 1;
else
state <= NGWR;
count <= X"0";
end if;
when NGWR =>
if count < sec11 then
state <= NGWR;
count <= count + 1;
else
state <= NYWR;
count <= X"0";
end if;
when NYWR =>
if count < sec3 then
state <= NYWR;
count <= count + 1;
else
state <=NRWG;
count <= X"0";
end if;
when others =>
state <= NRWG;
end case;
end if;
end if;
end if;
end process;
-----------decode state
OUTPUT_DECODE: process (state)
begin
case state is
when NRWG => Trafficlights <= "100001";
when NRWY => Trafficlights <= "100010";
when NGWR => Trafficlights <= "001100";
when NYWR => Trafficlights <= "010100";
when others => Trafficlights <= "100001";
end case;
end process;
--------------------------------
--------------Slow_Clock-------------
slow_clock:process(clck) begin
if(rising_edge(clck)) then
if(one_second_counter="10111110101111000010000000") then
one_second_counter <="00000000000000000000000000";
else
one_second_counter <= one_second_counter +1;
end if;
end if;
end process;
one_second_enable <= '1' when one_second_counter="10111110101111000010000000" else '0';
---------------------------------------------------
-----------------for debouncing---------------
debounce_emergency:process(clck)
begin
if(rising_edge(Clck)) then
case (state1) is
when idle =>
if(emergency = BTN_ACTIVE) then
state1 <= wait_time;
else
state1 <= idle;
end if;
emergency_debounced <= '0';
when wait_time =>
if(count1 = COUNT_MAX) then
count1 <= 0;
if(emergency = BTN_ACTIVE) then
emergency_debounced <= '1';
end if;
state1 <= idle;
else
count1 <= count1 + 1;
end if;
end case;
end if;
end process;
------------------------------------------------------------
---------edge_detector--------
edge_detection:process (clck)
begin
if(rising_edge(clck)) then
emergencya <= emergency_debounced;
emergencyb <= emergencya;
end if;
end process ;
emergencyc <= not emergencyb and emergencya;
---------------------------------
end Behavioral;
关于紧急功能为何无法正常工作的任何想法?
您的 debounce_emergency:process
在很多方面都是错误的。我建议您模拟您的设计以查看它。如果 emergency
按钮被按下 40 个时钟周期会怎样?
而且controller: process
中的if emergencyc='1' ...
部分必须在if rising_edge(clck)
里面,否则会触发状态信号的多次变化。
我正在尝试在交通灯控制器上实现 "emergency" 功能。
此紧急信号是一个 std_logic 输入,由按钮触发(使用 ucf 文件)。
这个信号的作用基本上是只要按下按钮,控制器就会检测到两条路(从北到南或从西到东)中的哪条路是红色的,它会立即将其切换为橙色(另一个当然会变成红色)让紧急车辆通过(例如救护车)。
我试过检测开关,然后将检测信号馈入上升沿检测器。它没有用:按下紧急按钮使两条路(NS 和 WE)的红灯和黄灯同时亮起,简直是一场灾难,我用来配置每盏灯亮多长时间的计数器也受到干扰好一阵子才恢复正常。
到目前为止,这是我的代码:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.std_logic_unsigned.all;
use ieee.numeric_std.all;
entity TLC is
Port (
Clck : in STD_LOGIC;
Reset: in STD_LOGIC;
emergency:in std_logic;
Trafficlights: out STD_LOGIC_Vector (5 downto 0) --trafficlights (5 downto 3) for the NS road and (2 downto 0) for the WE road.
);
end TLC;
architecture Behavioral of TLC is
-------------for debouncing
constant COUNT_MAX : integer := 20;
constant BTN_ACTIVE : std_logic := '1';
signal count1 : integer := 0;
type state_type1 is (idle,wait_time);
signal state1 : state_type1 := idle;
signal emergency_debounced:std_logic;
-----------------------------------------
type state_type is (NRWG, NRWY, NGWR, NYWR); --NRWG: North-South on red and West-East on green and so on.
signal one_second_counter: STD_LOGIC_vector(25 downto 0):="00000000000000000000000000";
signal one_second_enable: std_logic;
signal state: state_type:=NRWG;
signal count : std_logic_vector (3 downto 0);
constant sec8 : std_logic_vector ( 3 downto 0) := "1000";
constant sec3 : std_logic_vector (3 downto 0 ) := "0011";
constant sec11: std_logic_vector (3 downto 0 ) := "1011";
--edge detector signals
signal emergencya, emergencyb, emergencyc: std_logic;
----------
begin
controller: process (Clck,reset,emergencyc)
begin
if emergencyc='1' then
if state=NRWG or state=NRWY then ----if NS is on red then switch it to yellow.
state<=NYWR;
count<=x"0";
else
if state=NGWR or state=NYWR then ----if WE is on red then switch it to yellow.
state<=NRWY;
count<=x"0";
end if;
end if;
elsif reset ='1' then
state<=NRWG;
count<=X"0";
else
if rising_edge(clck) then
if one_second_enable='1' then
case state is
when NRWG =>
if count < sec8 then
state <= NRWG;
count <= count + 1;
else
state <= NRWY;
count <= X"0";
end if;
when NRWY =>
if count < sec3 then
state <= NRWY;
count <= count + 1;
else
state <= NGWR;
count <= X"0";
end if;
when NGWR =>
if count < sec11 then
state <= NGWR;
count <= count + 1;
else
state <= NYWR;
count <= X"0";
end if;
when NYWR =>
if count < sec3 then
state <= NYWR;
count <= count + 1;
else
state <=NRWG;
count <= X"0";
end if;
when others =>
state <= NRWG;
end case;
end if;
end if;
end if;
end process;
-----------decode state
OUTPUT_DECODE: process (state)
begin
case state is
when NRWG => Trafficlights <= "100001";
when NRWY => Trafficlights <= "100010";
when NGWR => Trafficlights <= "001100";
when NYWR => Trafficlights <= "010100";
when others => Trafficlights <= "100001";
end case;
end process;
--------------------------------
--------------Slow_Clock-------------
slow_clock:process(clck) begin
if(rising_edge(clck)) then
if(one_second_counter="10111110101111000010000000") then
one_second_counter <="00000000000000000000000000";
else
one_second_counter <= one_second_counter +1;
end if;
end if;
end process;
one_second_enable <= '1' when one_second_counter="10111110101111000010000000" else '0';
---------------------------------------------------
-----------------for debouncing---------------
debounce_emergency:process(clck)
begin
if(rising_edge(Clck)) then
case (state1) is
when idle =>
if(emergency = BTN_ACTIVE) then
state1 <= wait_time;
else
state1 <= idle;
end if;
emergency_debounced <= '0';
when wait_time =>
if(count1 = COUNT_MAX) then
count1 <= 0;
if(emergency = BTN_ACTIVE) then
emergency_debounced <= '1';
end if;
state1 <= idle;
else
count1 <= count1 + 1;
end if;
end case;
end if;
end process;
------------------------------------------------------------
---------edge_detector--------
edge_detection:process (clck)
begin
if(rising_edge(clck)) then
emergencya <= emergency_debounced;
emergencyb <= emergencya;
end if;
end process ;
emergencyc <= not emergencyb and emergencya;
---------------------------------
end Behavioral;
关于紧急功能为何无法正常工作的任何想法?
您的 debounce_emergency:process
在很多方面都是错误的。我建议您模拟您的设计以查看它。如果 emergency
按钮被按下 40 个时钟周期会怎样?
而且controller: process
中的if emergencyc='1' ...
部分必须在if rising_edge(clck)
里面,否则会触发状态信号的多次变化。