10.立ち上がりエッジをカウントする回路を作る
ここでは、これまで学んだ回路を組み合わせて回路を作成することを体験することができます。
ヒント(というより設計方針)
以下の通り、立ち上がりエッジを検出回路を前段において、この出力を次段のカウンターイネーブル信号の入力として構成することで実現できそうです。
ところで前段も次段も実はすでに設計済み(立ち上がりエッジ検出は8番、イネーブル付きカウンタは1番)ですので、一から設計することはせず、これらを再利用してトップ階層で接続するだけで動作します。
動作パターン図で示してみる
以下の通り入力dが立ち上がるごとに2クロック後の立ち上がりでカウントアップしている様子が分かると思います。
VHDLで書いてみる(トップ階層)
以下はトップ階層で、イネーブル付きカウンタ(encount回路)と、立ち上がり検出(upedge)を接続した記述をしています。これまでと違ってcomponent encount や、component upedge でそれぞれのモジュール(回路)を記述した後、port mapで各モジュールのin/outがどこと接続するのかを記述しています。お分かりになりますでしょうか。
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity upedgecount is
Port ( clk : in STD_LOGIC;
reset_n : in STD_LOGIC;
d: in STD_LOGIC;
cnt : out STD_LOGIC_VECTOR (3 downto 0));
end upedgecount;
architecture rtl of upedgecount is
signal ien : STD_LOGIC;
component encount
Port ( clk : in STD_LOGIC;
reset_n : in STD_LOGIC;
en : in STD_LOGIC;
q : out STD_LOGIC_VECTOR (3 downto 0));
end component;
component upedge
Port ( clk : in STD_LOGIC;
reset_n : in STD_LOGIC;
d: in STD_LOGIC;
up_edge_pulse : out STD_LOGIC);
end component;
begin
u1:upedge
port map ( clk => clk,
reset_n => reset_n,
d => d,
up_edge_pulse => ien);
u2:encount
port map ( clk => clk,
reset_n => reset_n,
en => ien,
q => cnt);
end rtl;
Verilogで書いてみる(トップ階層)
以下、ChatGPTでVerilog変換した結果を記載します。それにしてもVerilogの記述量の少なさは魅力的ですね~ (本人VHDL派)
module upedgecount (
input wire clk, // クロック入力
input wire reset_n, // アクティブローのリセット入力
input wire d, // データ入力
output wire [3:0] cnt // カウンタ出力
);
wire ien; // 上昇エッジ検出用の内部信号
// upedgeモジュールのインスタンス化
upedge u1 (
.clk(clk),
.reset_n(reset_n),
.d(d),
.up_edge_pulse(ien)
);
// encountモジュールのインスタンス化
encount u2 (
.clk(clk),
.reset_n(reset_n),
.en(ien),
.q(cnt)
);
endmodule
おわりに
今回は、これまで作成した回路を再利用して、トップ階層で接続するパターンをご紹介しました。階層設計はほぼ使われる手法ですから覚えておいて損はないでしょう。ありがとうございました。