0.カウンタを作る
回路設計では、カウンタが重要になります。正確なタイミングで信号を出力する必要があるためです。これを回路図(D型フリップフロップとANDやORの組み合わせ回路)で描くと大変ですが、言語で書くととても簡単に構成することができます。
回路図(シンボル)で示してみる
以下は回路図(シンボル)になります。
入力reset_nがLレベルの時は、出力q4本(4ビット)は全てLレベルにします。(すなわち0を示す)
リセットされていない(reset_nがH)の間は入力clkの立ち上がりでカウントアップし、出力qに出す、フリーランカウンタです。
動作パターン図で示してみる
以下に示します。入力reset_nがHになってから、入力clkの立ち上がりで出力q値(4ビット)がカウントアップします。
なお、4ビットが全てH(16進数でF)の次のクロック立ち上がりで全てL(16進数で0)になります。
さて、これを満たす回路を言語で記載してみるにはどうすればよいでしょうか?
VHDLで書いてみる
以下のようになります。
特に見ていただきたいのはprocess ~ end process; になります。優先して記述すべきことはまずリセットが入っているときのカウンタ値のふるまいになります。ここではリセットLレベルのときは、カウンタ値は全てLレベル(0)と記載します。
次にクロックの立ち上がりでカウントアップする記載をします。
たったこれだけです。
下部にq<= counter; とありますが、これはカウンタ値counterは内部信号であり、出力qとして出す場合に記載します。そのため、中部に signal counter : STD_LOGIC_VECTOR (3 downto 0);と記載し、counterは内部信号であることを定義しています。
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity fcnt is
Port ( clk : in STD_LOGIC;
reset_n : in STD_LOGIC;
q : out STD_LOGIC_VECTOR (3 downto 0));
end fcnt;
architecture rtl of fcnt 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
counter <= counter + 1;
end if;
end process;
q <= counter;
end rtl;
Verilogで書いてみる
以下になります。やはりVHDLよりコード量は少ないですね。
module fcnt (
input wire clk,
input wire reset_n,
output reg [3:0] q
);
reg [3:0] counter;
always @(posedge clk or negedge reset_n) begin
if (!reset_n)
counter <= 4'b0000;
else
counter <= counter + 1;
end
assign q = counter;
endmodule
おわりに
さて、D型フリップフロップやANDやOR等の組み合わせ回路を頭でイメージすることなく、動作を記述することでカウンタを作ることができました。言語設計を少しずつマスターしていきましょう。ありがとうございました。
この記事が気に入ったらサポートをしてみませんか?