アフィリエイト広告
アフィリエイト広告

加算器でカウンタを作る / 構成とシミュレーション

4ビット加算器を使った 4ビットカウンタを、ロジックICで作ります。

前回は、4ビット加算器をロジックICで作ってみました。

その過程で、加算器を使ってカウンタができんじゃねーのと思いついた。あ、思いついた、んじゃなくて、たぶん、どこかのサイトでそんな話をちょっと目にした、んだと思う m(_ _;)m
ので、今回は、4ビット加算器を使った 4ビットカウンタの構成を考え、シミュレーションしてみようと思います。

4ビット加算器による 4ビットカウンタ回路

カウンタとは数を数える回路です。数を数えるというのは 1 を足すということ。1 を足すのは加算器でできる。ということはつまり、加算器の出力にさらに 1 を足していけば、カウンタになる、はず。

ブロック図

4ビット加算器による 4ビットカウンタのブロック図です。

図 1. 4ビット加算器による 4ビットカウンタ ブロック図

ぱっと見、なんだかむずかしそうなブロック図ですが、考え方はさほどむずかしくはないです。

左側の FA-0 ~ FA-3 は全加算器です。4段つなぐことで 4ビット加算器になっています。これは、前回までに動作を確認したもの。
右側の DFF-0 ~ DFF-3 は Dフリップフロップによるストレージレジスタです。4個あるので 4ビット。4ビット加算器の出力を記憶します。

ストレージレジスタの出力 Q を加算器の B に入力します。加算する値 A には 0b0001、つまり 1 を入力しておきます。こうすることで、加算器の出力 S は Qn+1 になる。S はストレージレジスタに入り、クロックの立ち上がりで記憶され、加算器に戻る。再び 1 が加算されて S=Qn+2 になる。こうしてカウントアップされていきます。
S が 16 になると桁上がりを出力し、値は 0 に戻ります。でも、FA-3 の桁上がり Co は、どこにも接続されていない。つまり、無視される。ストレージレジスタの出力は 0 になり、結果、16進カウンタってことになります。

加算器によるカウンタ回路のシミュレーション

ブロック図をみていると、シミュレーションも難しそうに感じます。が、そこは VerilogHDL のすごいところで、とっても簡単です。

4ビット加算器はすでに動作を確認しています (過去記事) ので、単純に加算器として記述すればいいです。加算器の基本的な記述は、

【VerilogHDL】 加算器
  1. assign S = A + B;

これだけです。

Dフリップフロップは、クロックの立ち上がりで入力 D が Q へ出力されます。非同期リセット付き Dフリップフロップの基本的な記述は、

【VerilogHDL】 非同期リセット付き Dフリップフロップ
  1. always @(posedge CK or negedge RST) begin
  2.   if(1'b0 == RST)
  3.     Q <= 1'b0;
  4.   else
  5.     Q <= D;
  6. end

この 二つの回路を、それぞれ 4ビットにしてつなぐだけです。

回路記述

  1. module COUNTER_BY_ADDER_4BIT(
  2.   input wire CK, RST,
  3.   output reg [3:0] Q
  4. );
  5.   wire [3:0] S;
  6.   parameter [3:0] A = 4'b0001;
  7.   always @(posedge CK or negedge RST) begin
  8.     if(1'b0 == RST)
  9.       Q <= 4'b0;
  10.     else
  11.       Q <= S;
  12.   end
  13.   assign S = A + Q;
  14. endmodule

カウントアップするための加算する値 A は、パラメータとして設定しています。

テストベンチ

  1. module COUNTER_BY_ADDER_4BIT_TEST;
  2.   reg CK, RST;
  3.   wire [3:0] Q;
  4.   parameter STEP = 10;
  5.   COUNTER_BY_ADDER_4BIT COUNTER_BY_ADDER_4BIT(CK, RST, Q);
  6.   always begin
  7.     CK = 0; #(STEP/2);
  8.     CK = 1; #(STEP/2);
  9.   end
  10.   initial begin
  11.     RST = 0; #STEP;
  12.     RST = 1; #(STEP*25);
  13.     RST = 0; #STEP;
  14.     $finish;
  15.   end
  16.   initial begin
  17.     $dumpfile("counter_by_adder_4bit.vcd");
  18.     $dumpvars(0, COUNTER_BY_ADDER_4BIT_TEST);
  19.   end
  20. endmodule

テストベンチもこれまで同様、特に変わったところはありません。クロックを発生させ、リセット信号を制御するだけです。

シミュレーション結果

シミュレーションの結果です。

図 2. 4ビット加算器による 4ビットカウンタ シミュレーション結果

考えたとおりに、4ビット 16進カウンタとして動作しましたね。

ここでふと思った。1 を足すことでカウントアップするなら、-1 を足せばカウントダウンするんじゃね? -1 を足すとは 1 を引くこと。1 を引くとは補数 15 を足すということ。
補数とは?「足したらちょうど桁上がりする最小の数」です。16進数のばあい、0x1 に 0xF を足すと桁上がりして 0x10 になりますから、0x1 の補数は 0xF、2進数では 0b1111 です。

加算する数はパラメータ A に設定しています。パラメータは、テストベンチでインスタンス化するときに、パラメータ割り当てで変更できます。

  1.   COUNTER_BY_ADDER_4BIT #(4'b1111) COUNTER_BY_ADDER_4BIT(CK, RST, Q);

このときのシミュレーション結果が、図 3。

図 3. 4 ダウンカウンタ シミュレーション結果

ダウンカウンタになりましたね。加算器の入力 A を変更すれば、簡単にアップ、ダウンが切り換えられることがわかりました。

次回は

4ビット加算器を使った 4ビットカウンタは、考えたとおりに動きそうです。しかも、簡単にダウンカウンタにもなるみたい。

次回は、実際にロジックICで、このカウンタを組み立ててみます。で、シミュレーションでやったみたいに、アップカウンタとダウンカウンタとを切り換えられるようにもしてみましょう。

タイトルとURLをコピーしました