Вт июл 25, 2017 15:30:41
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity led_blink is
port (
clk : in std_logic; -- синхросигнал
btn : in std_logic; --кнопка
led : out std_logic_vector(3 downto 0) --выход на светодиоды
);
end led_blink;
architecture rtl of led_blink is
signal ONN_OFF : std_logic := '1';
signal state : std_logic_vector(3 downto 0) := "0001";
signal divider : unsigned(23 downto 0) := (others => '0'); --делитель частоты
begin
main_p : process(clk)
begin
if (rising_edge(clk)) then
if (divider < 5000000) then ---если меньше 5 млн. тактов, то счётчик наращивает 1
divider <= divider + 1;
else
divider <= (others => '0');--если больше,то счётчик сбрасывается в 0
if (btn = '1') then --если нажата кнопка
ONN_OFF <= not(ONN_OFF);--светодиоды загораются
if (ONN_OFF = '1') then
state <= state(2 downto 0) & state(3);
led <= state;
else --если НЕ нажата
led <= (others => '0');--сигнал на выход светодиодов не идёт
end if;
else
ONN_OFF <= '1';
led <= (others => '0');
end if;
end if;
end if;
end process;
end rtl;
library IEEE;
use IEEE.Std_logic_1164.all;
use IEEE.Numeric_Std.all;
entity led_blink_tb is
end;
architecture bench of led_blink_tb is
component led_blink
port (
clk : in std_logic;
btn : in std_logic;
led : out std_logic_vector(3 downto 0)
);
end component;
signal clk: std_logic;
signal btn: std_logic;
signal led: std_logic_vector(3 downto 0) ;
constant PERIOD : TIME := 100 ns;
constant DUTY_CYCLE : real := 0.5;
constant OFFSET : time := 3 ns;
begin
btn <= '0' after 500 ms, '1' after 3000 ms, '0' after 5000 ms, '1'after 9000 ms, '0' after 14000 ms, '1'after 20000 ms ;
uut: led_blink port map ( clk => clk,
btn => btn,
led => led );
clk_gen: PROCESS
BEGIN
WAIT for OFFSET;
CLOCK_LOOP : LOOP
CLK <= '0';
WAIT FOR (PERIOD - (PERIOD * DUTY_CYCLE));
CLK <= '1';
WAIT FOR (PERIOD * DUTY_CYCLE);
END LOOP CLOCK_LOOP;
END PROCESS;
end;
Ср авг 09, 2017 16:15:53
entity manual is
Port ( clk : in STD_LOGIC;
key : in STD_LOGIC;
set : out STD_LOGIC);
end manual;
architecture Behavioral of manual is
signal countdown: STD_LOGIC_VECTOR (4 downto 0) := conv_std_logic_vector(31,5);
constant start: std_logic_vector := conv_std_logic_vector(31,5);
constant repeat: std_logic_vector := conv_std_logic_vector(10,5);
begin
process (clk, key)
begin
if (clk'event and clk='1') then
if key='0' then
countdown <= start;
else
if (countdown = 0) then
countdown <= repeat;
else
countdown <= countdown - 1;
End IF;
End if;
End if;
end process;
set <= '1' when ((countdown = 0) or (countdown = (start-2))) else '0';
end Behavioral;
Этот модуль обеспечивает подавление дребезга контактов кнопки и автоповтор срабатывания. Это обеспечивается следующим образом. Главный элемент - пятиразрядный счетчик с обратным отсчетом (можно и с прямым, но мне так удобнее). Пока кнопка не нажата счетчик принудительно устанавливается в значение 31 (все лог.1). Как только кнопка будет нажата, счетчик начнёт свой обратный отсчет. Если кнопка будет удерживаться досточно долго (2/32 секунды), счетчик досчитает до 29 - пройдет импульс позволяющий инкрементировать счетчик часов или минут. Если кнопка будет отпущена, то вся система возвратится в исходное состояние, если нет - то счетчик продолжит свой обратный отсчет. Если счетчик досчитает до 0 (примерно через секунду) - пройдет следующий импульс установки времени. Однако, после того как счетчик достигнет нуля он не перейдет в состояние 31, а установится в значение 10, и уже с этого значения опять повторится обратный отсчет. Это обеспечит то, что повторные импульсы будут следовать с частотой, приблизительно, 3 импульса в секунду. В любой момент отпустив кнопку, система возвращается в исходное состояние.