記事一覧

スイッチをトグルする

2013年06月12日(水)16時21分

スイッチを押すたびに、出力が H L を繰り返す動作(トグル)はよくありますが、
T-Flip Flopを使用します。

回路は非常に単純です。

-- Togle using T-FF
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity TOGLE is
    port(
        TIN     : in  std_logic;
        RESET   : in  std_logic;
        TOUT    : out std_logic
    );
end TOGLE;

architecture RTL of TOGLE is
signal TOUT_TMP   : std_logic;

begin

    -- T-FF
    process(TIN,RESET)
    begin
        if (RESET = '0') then
            TOUT_TMP <= '0';
        elsif (TIN'event and TIN = '0') then
            TOUT_TMP <= not TOUT_TMP;
        end if;
    end process;
    
    TOUT <= TOUT_TMP;

end RTL;

チャタリングカット

2013年06月12日(水)14時22分

「改訂版 FPGAボードで学ぶ論理回路設計」の付属基盤は、チャタリング防止回路(RC回路)がありますが、

ファイル 82-1.jpg

ソフト的にチャタリングを防止してみます。

簡単な方法は、チャタリングがおさまる時間以上のクロックでサンプリングすれば良いのですが、
サンプリングは10ms前後でいいようです。

そこで、33MHz -> 約64Hz 15.625ms の分周をつくってみます。
非同期リセットも入れてます。
負論理です。

-- 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;

大雑把に1Hzをクロックする

2013年06月12日(水)00時26分

33MHzのクロックから約1Hzをつくります。

(33,000,000)10 *1 = (1 1111 0111 1000 1010 0100 0000) *2
なので 33MHzは25bit
そこで、33,000,000 / 2^25 *3 を計算すると 0.9834766Hz
1 / 0.9834766Hz ≒ 1.0168秒
まぁ、これくらいなら、よしとしましょうか(^_^;)

ここで、2進数のおさらい

例えば4bitは

0000
0001
0010
0011
0100
0101
0110
0111
1000
1001
---

1bit目に注目すると、0 1 0 1 0 1 0 1...
2bit目に注目すると、0 0 1 1 0 0 1 1...
3bit目に注目すると、0 0 0 0 1 1 1 1...

そうです、パルス、クロックですね。

最上位bitは1/2のサイクルで0,1を繰り返しているので、
25bitの最上位bitが0.9834766Hz、大雑把に1Hzのクロックということです。

また、下に1bitずらしていけば、2Hz 4Hz 8Hz...をつくることができます。

なお、非同期リセットを入れときました。
負論理になっています。

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_1HZ     : out std_logic;
        DIV_CLK_2HZ     : out std_logic;
        DIV_CLK_64HZ    : out std_logic
    );
end DIVIDER;

architecture RTL of DIVIDER is
    signal DIV_COUNTER : std_logic_vector(24 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_1HZ <= not DIV_COUNTER(24);
    DIV_CLK_2HZ <= not DIV_COUNTER(23);
    DIV_CLK_64HZ <= not DIV_COUNTER(18);

end RTL;

*1:10進法の33,000,000という意味です
*2:同様に 2進数の 1 1111 0111 1000 1010 0100 0000 です
*3:2の25乗