見出し画像

4.任意のカウント値で値をクリアするカウンタを作る

ここでは、任意のカウント値で値をクリアするカウンタを作ってみましょう。

回路図(シンボル)で示してみる

イネーブル付きのカウンタの後段に出力iq値を14(16進数のE)と比較して一致したらカウント値を0に戻す回路になります。

任意のカウント値で値をクリアするカウンタの図

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

下図の通りenがHでカウンタ値がアップしていきますが、16進数でEになったら、その次のクロックの立ち上がりでenの状態に関係なく0に戻しています。さて、これを満たす回路を言語で記載してみるにはどうすればよいでしょうか?

任意のカウント値で値をクリアするカウンタの動作パターンの図

VHDLで書いてみる

以下のようになります。ただのカウンタと異なるところは、
elsif rising_edge(clk) then
 if counter = "1110" then
  counter <= (others => '0');
 elsif en = '1' then
  counter <= counter + 1;
であり、カウントアップの記述より上に、カウンタが14(2進数の1110)の時に0にする記載をすることで、enイネーブルがHでカウントアップするよりも優先するようにしています。

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

entity encount14cmp is
    Port ( 	clk : in  STD_LOGIC;
           	reset_n : in  STD_LOGIC;
           	en : in STD_LOGIC;
           	q : out  STD_LOGIC_VECTOR (3 downto 0));
end encount14cmp;

architecture rtl of encount14cmp is
    signal counter : STD_LOGIC_VECTOR (3 downto 0);
begin
    process(clk, reset_n)
    begin
        if reset_n = '0' then
            counter <= (others => '0');
        elsif rising_edge(clk) then
        	if counter = "1110" then
        		counter <= (others => '0');
        	elsif en = '1' then
            		counter <= counter + 1;
        	end if;
        end if;
    end process;
    
    q <= counter;
end rtl;

Verilogで書いてみる

同様にverilogで記載してみます。

module encount14cmp (
    input wire clk,
    input wire reset_n,
    input wire en,
    output reg [3:0] q
);

reg [3:0] counter;

always @(posedge clk or negedge reset_n) begin
    if (!reset_n)
        counter <= 4'b0000;
    else if (counter == 4'b1110)
        counter <= 4'b0000;
    else if (en)
        counter <= counter + 4'b0001;
end

assign q = counter;

endmodule

おわりに

「カウンタを作る」「イネーブル付きのカウンタを作る」「ロード付きのカウンタを作る」、「ロード・イネーブル付きのカウンタを作る」に加え、「任意のカウント値で値をクリアするカウンタを作る」で、だいぶ言語設計に慣れてきたのではないでしょうか。ありがとうございました。

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