在Spartan 3E上通过按钮触发短脉冲信号

时间:2019-07-16 21:38:46

标签: vhdl fpga digital spartan

我正在尝试在交通信号灯控制器上实现“紧急”功能。

此紧急信号是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;

关于紧急功能为何无法正常运行的任何想法?

1 个答案:

答案 0 :(得分:1)

您的debounce_emergency:process在许多方面都是错误的。我建议您模拟设计以查看它。如果按下emergency按钮40个时钟周期会怎样?

此外,controller: process中的if emergencyc='1' ...部分必须位于if rising_edge(clck)内,否则将触发状态信号的多个变化。