信号を1m秒間隔で出力する回路を作成。いくつかブロック図を作ってから最適な回路構成を選び、HDLを記述するのがポイントだ。
前回の宿題【問題10】は、“1m秒間隔で信号を出力する回路を作成する”という問題でした。皆さん解けましたでしょうか?
解けた方も解けなかった方も答え合わせをして、次項の解説までぜひ読んでみてください。毎週コツコツ問題を解いて、ハードウェア記述言語によるデジタル回路設計の基礎知識を身に付けましょう。
それでは、解答を発表します!
【問題10】は、図1のような信号を1m秒間隔で出力する回路を作成する問題です。
前回解説したとおり、新たに回路を作成するときは、いきなりHDLを書こうとしないで、まずはブロック図で回路構成を考えます。それでは早速はじめましょう。
図2をご覧ください。【問題10】の出力Qは1m秒ごとに変化するので、まずカウンタでクロックCLKの1/4000のイネーブル信号ENを作ります。さらに、カウンタでcntを00、01、10、11と変化させ、それからデコーダ(表1)で出力Q(0001、0010、0100、1000、……)を作ります。
入力 cnt[1:0] |
出力 Q[3:0] |
|
---|---|---|
00 | 0001 | |
01 | 0010 | |
10 | 0100 | |
11 | 1000 | |
表1 デコーダ(図2)の真理値表 |
さらに、図2とは別の回路構成も考えられます(図3)。
1m秒ごとのイネーブル信号ENを作るという点については図2と変わりませんが、図3ではシフトレジスタにより直接出力Qを作り出しています。
以上のように、いくつか(今回は2つですが)ブロック図を作って、最適な回路構成を選んだ後、HDLを記述すると、素晴らしい回路が出来上がります。
今回は、図3「回路構成(その2)」を基にVerilog HDLをコーディングしていきます。
1/4000カウンタは、次のように記述します。
always @(posedge CLK or negedge RES) if (RES == 1'b0) scale <= 12'd0; else if (scale == 12'd3999) scale <=12'd0; else scale <= scale + 12'd1;
そして、イネーブル信号ENは、
assign EN = scale == 12'd3999;
で作ることができます。
巡回シフトについては集合演算子(“{”と“}”)を使って、
Q <= {Q[2:0],Q[3]};
と記述できます。ちなみにこの記述は、「変数Qの下位3ビットQ[2:0]の後ろに、最上位ビットQ[3]をつなぐ」という意味です。
また、イネーブル付きシフトレジスタは、次のように記述します。
always @(posedge CLK or negedge RES) if (RES == 1'b0) Q <= 4'b0001; else if (EN == 1'b1) Q <= {Q[2:0],Q[3]};
以上で回路の完成です(shift.v)。
Copyright © ITmedia, Inc. All Rights Reserved.