動作の基本となるクロックから分周回路をつくります。
元のクロックは33MHzです。
これから2Hz 8Hz 16Hz 32Hzを作成します。
-- Divider
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity DIVIDER is
port(
CLK : in std_logic;
RESET : in std_logic;
DIV_CLK_2HZ : out std_logic;
DIV_CLK_8Hz : out std_logic;
DIV_CLK_16Hz: out std_logic;
DIV_CLK_32HZ: out std_logic
);
end DIVIDER;
architecture RTL of DIVIDER is
constant CLK_BIT : integer := 25; --Osc 33MHz: 25bit
signal DIV_COUNTER : std_logic_vector(CLK_BIT-1 downto 0);
begin
process(CLK,RESET)
begin
if (RESET = '0') then
DIV_COUNTER <= (others => '0');
elsif (CLK'event and CLK = '0') then
DIV_COUNTER <= DIV_COUNTER + 1;
end if;
end process;
DIV_CLK_2HZ <= not DIV_COUNTER(CLK_BIT-2);
DIV_CLK_8HZ <= not DIV_COUNTER(CLK_BIT-4);
DIV_CLK_16HZ <= not DIV_COUNTER(CLK_BIT-5);
DIV_CLK_32HZ <= not DIV_COUNTER(CLK_BIT-6);
end RTL;
チャタリングは64Hz = 15.625msのサイクルで除去します。
chattering_cut.vhd
-- Chattering CUT rate about 64Hz 15.625ms
-- InPutClock 33MHz
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity CHATTERING_CUT is
port(
SW : in std_logic;
CLK : in std_logic;
RESET: in std_logic;
COUT : out std_logic
);
end CHATTERING_CUT;
architecture RTL of CHATTERING_CUT is
signal DIV_COUNTER : std_logic_vector(24 downto 0);
signal DIV_CLK_64HZ : std_logic;
begin
process(CLK,RESET)
begin
if (RESET = '0') then
DIV_COUNTER <= (others => '0');
elsif (CLK'event and CLK = '0') then
DIV_COUNTER <= DIV_COUNTER + 1;
end if;
end process;
DIV_CLK_64HZ <= not DIV_COUNTER(18);
process(DIV_CLK_64HZ)
begin
if (DIV_CLK_64HZ'event and DIV_CLK_64HZ ='0') then
COUT <= SW;
end if;
end process;
end RTL;
64Hzのクロックは分周からひっぱってきても良いですが、
遅延を考えると元クロックから作成したほうが良いでしょう。*1
*1:その場合、消費電力の問題が発生します。