После обновления вашего кода осталось несколько проблем:
Часы не генерируются в тестовой среде
Стимулы ( нажатия кнопок) не рассчитываются по времени в тестовой среде
Средство защиты от сбоев не производит enable для отдельных часов
Чтобы облегчить моделирование для дизайна проверку , ваш дизайн был изменен, чтобы позволить более медленные часы (похоже, вы фактически используете тактовую частоту 100 МГц). Идея состоит в том, чтобы уменьшить требования к вычислениям и отображению формы сигналов.
Первые две точки рассматриваются в тестовой среде:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity button_counter_tb is
end entity button_counter_tb;
architecture behavioral of button_counter_tb is
-- NOTE: suffix _tb has been removed, it's annoying to type over and over
signal clk: std_logic := '0'; -- ADDED default value '0'
signal btnU: std_logic;
signal btnD: std_logic;
signal led: std_logic_vector (15 downto 0);
component button_counter
generic ( -- ADDED generic
CLKP: time := 10 ns;
DEBT: time := 6.5 ms -- debounce time supports different
); -- mechanical buttons/switches
port (
clk: in std_logic;
btnU: in std_logic;
btnD: in std_logic;
led: out std_logic_vector (15 downto 0)
);
end component;
constant CLKP: time := 12.5 us; -- ADDED just long enough to show debounce
constant DEBT: time := 6.5 ms; -- ADDED
begin
CLOCK: -- ADDED clock process
process
begin
wait for CLKP/2;
clk <= not clk;
if now > 2 sec then -- stop simulation
wait;
end if;
end process;
UUT:
button_counter
generic map ( -- ADDED generic map
CLKP => CLKP,
DEBT => DEBT
)
port map (
clk => clk,
btnU => btnU,
btnD => btnD,
led => led
);
-- STIMULI:
-- process
-- begin
-- btnU_tb <= '0';
-- btnD_tb <= '0';
-- wait for 100 ns;
-- btnU_tb <= '1';
-- wait for 100 ns;
-- btnU_tb <= '0';
-- wait for 100 ns;
-- btnU_tb <= '1';
-- wait for 100 ns;
-- btnD_tb <= '1';
-- wait for 100 ns;
-- btnU_tb <= '0';
-- wait for 100 ns;
-- btnD_tb <= '0';
-- wait; -- ADDED -- stops simulation
-- end process;
UP_BUTTON:
process
begin
btnU <= '0';
wait for 2 ms;
btnU <= '1'; -- first button press
wait for 0.5 ms;
btnU <= '0';
wait for 0.25 ms;
btnU <= '1';
wait for 7 ms;
btnU <= '0';
wait for 100 us;
btnU <= '1';
wait for 20 us;
btnU <= '0';
wait for 200 ms;
btnU <= '1'; -- second button press
wait for 20 us;
btnU <= '0';
wait for 20 us;
btnU <= '1';
wait for 6.6 ms;
btnU <= '0';
wait for 250 ms;
btnU <= '1'; -- third button press
wait for 20 us;
btnU <= '0';
wait for 20 us;
btnU <= '1';
wait for 6.6 ms;
btnU <= '0';
wait for 200 ms;
btnU <= '1'; -- second button press
wait for 20 us;
btnU <= '0';
wait for 20 us;
btnU <= '1';
wait for 6.6 ms;
btnU <= '0';
wait for 50 us;
btnU <= '1';
wait for 1 ms;
btnU <= '0';
wait;
end process;
DOWN_BUTTON:
process
begin
btnD <= '0';
wait for 800 ms;
btnD <= '1'; -- first button press
wait for 0.5 ms;
btnD <= '0';
wait for 0.25 ms;
btnD <= '1';
wait for 0.5 ms;
btnD <= '0';
wait for 1 ms;
btnD <= '1';
wait for 7 ms;
btnD <= '0';
wait for 100 us;
btnD <= '1';
wait for 20 us;
btnD <= '0';
wait for 200 ms;
btnD <= '1'; -- second button press
wait for 20 us;
btnD <= '0';
wait for 20 us;
btnD <= '1';
wait for 6.6 ms;
btnD <= '0';
wait for 250 ms;
wait;
end process;
end architecture behavioral;
Суффикс _tb
для имен сигналов был удален ( было больно набирать повторно).
Период тактов был выбран с отношением периода отказов к периоду clk, гарантированно позволяющего отбрасывать «отказов». Нажатие стимулирующих кнопок может быть расширено, как и симуляция, которая здесь произвольна.
Обратите внимание, что значения нажатия кнопки гарантированно охватывают один или несколько интервалов времени. Они должны допускать изменение периода часов путем изменения CLKP
.
Интервал дребезга DEBT можно изменить, чтобы отразить использование различных переключателей или кнопок, включая мембранные переключатели с серьезным старением. Интервал дребезга является следствием механических характеристик конкретных переключателей или кнопок. Передача этих общих констант c обеспечивает некоторую независимость от платформы.
Третья точка решается путем изменений в противодействии:
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
entity debouncer is
generic ( -- ADDED GENERICS to speed up simulation
CLKP: time := 10 ns;
DEBT: time := 6.5 ms
);
port (
clk: in std_logic;
btn: in std_logic;
btn_clr: out std_logic
);
end entity debouncer;
architecture behavioural of debouncer is
-- constant delay: integer := 650000; -- 6.5ms
constant DELAY: integer := DEBT/CLKP;
signal count: integer := 0;
signal b_enab: std_logic := '0'; -- RENAMED, WAS btn_tmp
signal btnd0: std_logic; -- ADDED for clock domain crossing
signal btnd1: std_logic; -- DITTO
begin
CLK_DOMAIN_CROSS: -- ADDED process
process (clk)
begin
if rising_edge(clk) then
btnd0 <= btn;
btnd1 <= btnd0;
end if;
end process;
DEBOUNCE_COUNTER: -- ADDED LABEL
process (clk)
begin
if rising_edge(clk) then
-- if btn /= btn_tmp then -- REWRITTEN
-- btn_tmp <= btn;
-- count <= 0;
-- elsif count = DELAY then
-- btn_clr <= btn_tmp;
-- else
-- count <= count + 1;
-- end if;
btn_clr <= '0'; -- btn_clr for only one clock, used as enable
if btnd1 = '0' then -- test for btn inactive state
count <= 0;
elsif count < DELAY then -- while btn remains in active state
count <= count + 1;
end if;
if count = DELAY - 1 then -- why btn_clr '1' or 1 clock
btn_clr <= '1';
end if;
end if;
end process;
end architecture behavioural;
Дебаундер был изменен для получения домена часов значение кнопки, которое используется для сброса и включения счетчика count
. Выходное имя btn_clr
осталось неизменным и истинно только для одного такта и может использоваться в качестве разрешения.
CLKP
и DEBT
используются вместе, чтобы обеспечить более быстрое выполнение симуляции при передаче одного и того же время моделирования.
Обратите внимание, что активное состояние ввода кнопки жестко запрограммировано. Они будут подключены к контактам устройства, где можно указать полярность входа.
Изменения в button_counter передают generi c константы CLKP
и DEBT
средствам защиты:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity button_counter is
generic (
CLKP: time := 10 ns; -- GENERIC CONSTANTS for faster simulation
DEBT: time := 6.5 ms -- supports diffeent switches/buttons
);
port (
clk: in std_logic;
btnU: in std_logic;
btnD: in std_logic;
led: out std_logic_vector (15 downto 0)
);
end entity button_counter;
architecture behavioral of button_counter is
component debouncer is
generic (
CLKP: time := 10 ns;
DEBT: time := 6.5 ms
);
port (
clk: in std_logic;
btn: in std_logic;
btn_clr: out std_logic
);
end component;
signal btnU_clr: std_logic;
signal btnD_clr: std_logic;
begin
debouncer_btnU:
debouncer
generic map (
CLKP => CLKP,
DEBT => DEBT
)
port map (
clk => clk,
btn => btnU,
btn_clr => btnU_clr
);
debouncer_btnD:
debouncer
generic map (
CLKP => CLKP,
DEBT => DEBT
)
port map (
clk => clk,
btn => btnD,
btn_clr => btnD_clr
);
process (clk)
variable count: integer := 0;
begin
if rising_edge(clk) then
if btnU_clr = '1' then
count := count + 1;
elsif btnD_clr = '1'then
count := count - 1;
end if;
led <= std_logic_vector(to_unsigned(count, led'length));
end if;
end process;
end architecture behavioral;
И при моделировании мы теперь видим, как светодиоды подсчитывают вверх и вниз:
Запуск тестовой среды и отображение различных форм сигналов позволит «увеличить масштаб» для отображения обработки сбоев в двух модулях защиты от сбоев. .
Модификации для передачи тактового сигнала и интервала устранения дребезга через иерархию дизайна не будут строго существенными. Они облегчают моделирование, которое используется, как здесь, для подтверждения конструкции. (Стимулы, показанные в тестовом стенде, не подтверждают полностью дизайн).
При использовании общих c значений по умолчанию (с тактовой частотой 100 МГц) есть очень хорошие шансы, что проект будет работать при реализации в целевом объекте. Платформа. (Активная полярность ввода кнопок выбирается в противодействии с целью поддержки исходной реализации. Если вы подозреваете, что кнопка отскакивает при увеличении или уменьшении, вы можете увеличить значение DEBT.)
Если конкретный инструмент синтеза не может значение дескриптора типа time
, переданное как общие константы c, вы можете преобразовать различные объявления CLKP
и DEBT
в тип integer
или просто передать максимальное количество.