VHDLで信頼性の高いタイマーを構築:クロックサイクルカウントで時間を計測
以前のチュートリアルではシミュレーションで時間を遅延させるためにwait for文を使用しました。しかし、wait forは本番設計では使用できません。実際の回路に一時停止を指示できないためです。VHDLモジュールで時間を測る実用的な方法は、クロックサイクルを数えることです。
すべてのデジタル設計には既知の周波数で発振する安定したクロック信号があります。クロックが100MHzなら、1秒は1億クロックティックに相当。これらのティックを数えることで、秒、分、時間、それ以上を確実に生成できます。
この記事はBasic VHDL Tutorialsシリーズの一部です。
クロックの立ち上がりエッジごとにインクリメントするカウンタを実装します。カウンタがクロック周波数値に達したら1秒経過として「秒」カウンタをインクリメント。同様に分(60秒後)、時間(60分後)と連鎖できます。追加カウンタで日、週、月も可能。FPGA/ASICリソースと必要カウンタ幅のみが制限となります。
より長いカウンタはより多くのロジックリソースを消費し、伝播遅延も増大します。カウンタチェーンのクリティカルパスがクロック周期内に収まらなければ合成は失敗します。
演習:タイマーの実装
以下のVHDLテストベンチは、シミュレーション時間を適切に保つため10Hzクロックを使用するシンプルな例です。DUTはSeconds、Minutes、Hours信号を出力するタイマーです。
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity T18_TimerTb is
end entity;
architecture sim of T18_TimerTb is
-- 高速シミュレーション用低速クロック
constant ClockFrequencyHz : integer := 10; -- 10 Hz
constant ClockPeriod : time := 1000 ms / ClockFrequencyHz;
signal Clk : std_logic := '1';
signal nRst : std_logic := '0';
signal Seconds : integer;
signal Minutes : integer;
signal Hours : integer;
begin
-- Device Under Test (DUT)
i_Timer : entity work.T18_Timer(rtl)
generic map(ClockFrequencyHz => ClockFrequencyHz)
port map (
Clk => Clk,
nRst => nRst,
Seconds => Seconds,
Minutes => Minutes,
Hours => Hours
);
-- クロックジェネレータ
Clk <= not Clk after ClockPeriod / 2;
-- テストベンチシーケンス
process is
begin
wait until rising_edge(Clk);
wait until rising_edge(Clk);
-- リセット解除
nRst <= '1';
wait;
end process;
end architecture;
以下がタイマーモジュール本体。ティック、秒、分、時をカウントし、負論理リセット(nRst)アサート時に全カウンタをリセットします。
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity T18_Timer is
generic(ClockFrequencyHz : integer);
port(
Clk : in std_logic;
nRst : in std_logic; -- 負論理リセット
Seconds : inout integer;
Minutes : inout integer;
Hours : inout integer
);
end entity;
architecture rtl of T18_Timer is
-- クロック周期カウント
signal Ticks : integer;
begin
process(Clk) is
begin
if rising_edge(Clk) then
if nRst = '0' then
Ticks <= 0; Seconds <= 0; Minutes <= 0; Hours <= 0;
else
if Ticks = ClockFrequencyHz - 1 then
Ticks <= 0;
if Seconds = 59 then
Seconds <= 0;
if Minutes = 59 then
Minutes <= 0;
if Hours = 23 then
Hours <= 0;
else
Hours <= Hours + 1;
end if;
else
Minutes <= Minutes + 1;
end if;
else
Seconds <= Seconds + 1;
end if;
else
Ticks <= Ticks + 1;
end if;
end if;
end if;
end process;
end architecture;
波形は正しい動作を確認:Secondsは毎ティックインクリメント、Minutesは60秒後、Hoursは60分後にインクリメント。
シミュレーションではModelSimでrun 50 hrコマンドにより50時間テストを実行(10Hzクロックで実行時間を管理)。テストベンチのクロック周波数調整は検証高速化の一般的戦略です。
実ハードウェアではカウンタチェーンが1クロック周期内に完了しなければなりません。カウンタ幅が増えると伝播遅延が増大し、周期を超えてタイミング違反を引き起こす可能性があります。正確な限界はFPGA/ASICファミリとクロック速度に依存。
重要なポイント
- VHDLでの時間計測はクロックサイクルカウントで達成される。
- テストベンチクロック周波数を下げると、設計を変更せずにシミュレーションを高速化できる。
次のチュートリアルで高度なタイマー機能を学習します。
VHDL
- VHDLで文字列リストを作成する: ベスト・プラクティスと実装例
- Tcl駆動テストベンチでVHDLコード・ロック・モジュールを検証する
- VHDLテストベンチ・シミュレーションを優雅に終了させる方法
- VHDLでPWMコントローラを実装: 設計、シミュレーション、FPGAデモ
- VHDLで乱数生成: 一様分布からOSVVMまで
- ブロックRAMにおける堅牢なVHDLリングバッファFIFOの設計
- VHDLで自己検証テストベンチを構築する実践ガイド
- VHDLで保護型とアクセスポインタを用いた動的リンクリスト実装
- プロセス内プロシージャでVHDLステートマシンをクリーンに設計
- VHDLにおける不純関数の活用:FSMの可読性と保守性向上
- VHDL関数マスター:効率的な設計のための実践ガイド