見出し画像

9.立ち下がりエッジ検出回路を作る

ここでは、ある信号がH→Lになった時に、H→Lへ立ち下がったことを検出する「立ち下がりエッジ検出回路」についてご紹介します。実践で良く使われる手法ですのでぜひ覚えておきましょう。

ヒント(というより設計方針)

dの信号の立ち下がりエッジを検出するにはどう組めば良いでしょうか?下図はその手がかりとして描いた回路図となります。D型フリップフロップの後段の?のところを考えた上で全体の回路を考えてみましょう。

動作パターン図で示してみる

以下の通り、d信号がH→Lになると直後のクロックの立ち上がりで1クロック分Hの信号を出力down_edge_pulse信号から出していることが分かると思います。さて、どうすればできるでしょうか。

立ち下がりエッジ検出回路の動作パターンの図

VHDLで書いてみる

以下の通りになります。見ての通り回路図をそのまま言語に移植した記述になっているので、ここから回路図を想像することが可能です。idf1というのは、ヒントで記載した前段のフリップフロップの出力信号になっています。
その次に記述しているidf2の入力がidf1の出力と接続されているのがお分かりになりますでしょうか。要するにidf1の後段もD型のフリップフロップで構成されています。そして、最終段に記述がある通り、前段のD型フリップフロップの出力idf1のnotと、後段のD型フリップフロップの出力idf2をANDした結果が出力udown_edge_pulseとなります。この程度であれば一旦ご自身で手書きでタイムチャートを書いて確認することができると思いますので、やってみるのも良いでしょう。

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity downedge is
    Port ( 	clk : in  STD_LOGIC;
           	reset_n : in  STD_LOGIC;
           	d: in STD_LOGIC;
           	down_edge_pulse : out  STD_LOGIC);
end downedge;

architecture rtl of downedge is
    signal idf1 : STD_LOGIC;
    signal idf2 : STD_LOGIC;

begin
    process(clk, reset_n)
    begin
        if reset_n = '0' then
            idf1 <= '0';
        elsif rising_edge(clk) then
			idf1 <=d;
        end if;
    end process;
    
    process(clk, reset_n)
    begin
        if reset_n = '0' then
            idf2 <= '0';
        elsif rising_edge(clk) then
			idf2 <=idf1;
        end if;
    end process;
    
    down_edge_pulse <= (not idf1) and idf2;
    
end rtl;

Verilogで書いてみる

以下ChatGPTでVerilog変換していますが、解説が付いているので分かりやすいですね。記述は違えどやっていることは全く同じです。

module downedge (
    input wire clk,            // クロック入力
    input wire reset_n,        // アクティブローのリセット入力
    input wire d,              // データ入力
    output reg down_edge_pulse // 立ち下がりエッジ検出時の出力パルス
);

    reg idf1;
    reg idf2;

    // idf1の更新
    always @(posedge clk or negedge reset_n) begin
        if (!reset_n) begin
            idf1 <= 1'b0;
        end else begin
            idf1 <= d;
        end
    end

    // idf2の更新
    always @(posedge clk or negedge reset_n) begin
        if (!reset_n) begin
            idf2 <= 1'b0;
        end else begin
            idf2 <= idf1;
        end
    end

    // 立ち下がりエッジ検出
    always @* begin
        down_edge_pulse = ~idf1 & idf2;
    end

endmodule

おわりに

立ち下がり検出回路はよく使われますので覚えておいて損はないと思います。ありがとうございました。

この記事が気に入ったらサポートをしてみませんか?