見出し画像

5.カウンタと比較器を作る~その1

ここでは、カウンタとカウント値を比較して任意の出力をする比較器を作ってみましょう。

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

イネーブル付きのカウンタの後段に出力iq値を2~10の範囲内かどうか比較して範囲内なら出力outsigをHにし、そうでなければLにする回路になります。

カウンタと比較器の図

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

下図の通りenがHでカウンタ値がアップしていきますが、カウント値が2~10(16進数でA)になったら、出力outsigをHにし、そうでなければLになっています。さて、これを満たす回路を言語で記載してみるにはどうすればよいでしょうか?

カウンタと比較器の動作パターン図

VHDLで書いてみる

下部のprocess(counter)以下が比較器になります。
説明するまでもないでしょう。

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;library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

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

architecture rtl of encount2acmp 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 en = '1' then
            	counter <= counter + 1;
        	end if;
        end if;
    end process;
    
    q <= counter;
    
    process(counter)
    begin
    	if (counter >= x"2") and (counter <= x"a") then
    		outsig <= '1';
    	else
    		outsig <= '0';
    	end if;
    end process;
    
end rtl;

Verilogで書いてみる

後段の always @(counter) begin が比較器になります。

module encount2acmp (
    input wire clk,
    input wire reset_n,
    input wire en,
    output reg outsig,
    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 (en)
        counter <= counter + 4'b0001;
end

always @(counter) begin
    if (counter >= 4'h2 && counter <= 4'hA)
        outsig <= 1'b1;
    else
        outsig <= 1'b0;
end

assign q = counter;

endmodule

おわりに

だいぶ言語設計に慣れてきたのではないでしょうか。ありがとうございました。

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