Я пытаюсь реализовать «аварийную» функцию на контроллере светофора.
Этот аварийный сигнал является входом 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)
, иначе вызовет множественные изменения в сигнале состояния.
Спасибо, я специально поставил аварийный сигнал как асинхронный, потому что его нужно активировать всякий раз, когда есть чрезвычайная ситуация, независимо от часов.
Ваш код не читается. Начните с написания VHDL вместо портированного Verilog. Основными причинами использования VHDL являются строгая типизация и моделирование дельта-цикла за счет потери гибкости. Простое размещение std_logic и дюжины комбинаторных процессов делает невозможным отслеживание вашего потока.