任意の分解能のPWM(Pulse Width Modulation)信号を発生させるPLD(Programmable Logic Device)コードを紹介する。
リスト1に示したPLD(Programmable Logic Device)コードは、任意の分解能のPWM(Pulse Width Modulation)信号を発生させるものだ。PWM信号発生器は、マイクロプロセッサを使ったシステムにおいて、帯域幅が狭いD-A変換器として利用できる。
PWM信号は、簡単なRC低域通過フィルターを通すと、PWM信号のデューティー比と電源電圧との積にほぼ等しい電圧値に変換できるからだ。ただし実際のシステムでは、駆動用のハードウェアが不完全であるため、最小値はゼロにならず、最大値も電源電圧に等しくならない。
INCLUDE "LPM_COUNTER.INC"; INCLUDE "LPM_COMPARE.INC"; INCLUDE "LPM_FF.INC"; PARAMETERS ( PWM_WIDTH = 6, -- Bits (set to 6 for testing) AVALUE = B"100000" -- Async reset value ); SUBDESIGN pwm ( clock : INPUT; aclr : INPUT; enable : INPUT = VCC; -- zeros PWM output write : INPUT; -- writes into holding register data[PWM_WIDTH-1..0] : INPUT; q : OUTPUT; -- period_pulse : OUTPUT; -- for debug and ext sync -- cout : OUTPUT; ) VARIABLE pwm : LPM_COUNTER WITH (LPM_WIDTH = PWM_WIDTH, LPM_DIRECTION = "DOWN"); cntr LPM_COUNTER WITH (LPM_WIDTH = PWM_WIDTH, LPM_DIRECTION = "DOWN"); pwm_ff SRFF; pwm_reg LPM_FF WITH (LPM_WIDTH = PWM_WIDTH, LPM_AVALUE = AVALUE); pwm_preout : NODE; period_pulse : NODE; -- for debug and ext sync cout : NODE; BEGIN ASSERT REPORT "PWM_WIDTH: %" PWM_WIDTH SEVERITY INFO; % PWM Holding Register % pwm_reg.clock = clock; pwm_reg.aset = aclr; pwm_reg.enable = write; pwm_reg.data[] = data[]; % PWM Counter % cntr.clock = clock; cntr.aclr = aclr; cntr.cnt_en = enable; period_pulse = DFF(cntr.cout, clock, !aclr, VCC); % PWM Counter % pwm.clock = clock; pwm.aclr = aclr; pwm.sload = cntr.cout; pwm.data[] = pwm_reg.q[]; pwm.cnt_en = enable; cout = pwm.cout; % PWM Output F/F % pwm_ff.clk = clock; pwm_ff.clrn = !aclr; pwm_ff.s = !cout AND period_pulse; -- turn FF on at beginning of interval pwm_ff.r = cout OR !enable; -- turn off at carry overflow. pwm_preout = pwm_ff.q; q = DFF(enable AND pwm_preout, clock, !aclr, VCC); END;
リスト1のプログラムは、PWM_WIDTHとAVALUEという2つのコンパイルタイムパラメーターを使って、所望のハードウェアを自動的に生成するものだ。PWM_WIDTHは、PWM信号のデューティー比のステップ数を設定する。例えば6ビットと設定するとステップ数は26、すなわち64になる。AVALUEは電源投入時、もしくはリセット時のPWMの初期値を設定する。リスト1では、半分のスケールに設定している。
このプログラムは、2つの主要なセクションから構成されている。1つは、PWM値を格納するホールディングレジスター、もう1つはPWM波形を生成するカウンターである。ホールディングレジスターはPWMカウンターとは独立に更新できる。PWMカウンターがオーバーフローしたときは、ホールディングレジスターの値が自動的にPWMカウンターに転送される。
このプログラムには、CLOCKとACLR、ENABLE、DATA[PWM_WIDTH-1..0]などの入力がある。CLOCKはマスターのシステムクロックである。ACLR以外の信号は全て、このクロックの立ち上がりエッジに同期する。ACLRは電源投入時にハードウェアを初期化し、AVALUEの値をホールディングレジスターに格納する役割を果たす。
ENABLE=0のときは、PWM出力は0(オフ)になる。ENABLE=1になると、PWM波形をQ出力に発生させる。WRITEのアサートが1クロックサイクル続いたことを確認すると、DATA[PWM_WIDTH-1..0]に入力されたデータをホールディングレジスターに転送する。
PLDコードはAlteraのハードウェア記述言語「AHDL」で記述した。このコードは、同社のPLDであれば直接コンパイルできる。PLDとして「EPIK10TC100-3」を使えば、最大139MHzで動作する(パラメーターはリスト1に記述したものを使用)。このプログラムはVHDLやVerilog HDLに簡単に変換できる。
【アナログ機能回路】:フィルター回路や発振回路、センサー回路など
【パワー関連と電源】:ノイズの低減手法、保護回路など
【ディスプレイとドライバー】:LEDの制御、活用法など
【計測とテスト】:簡易テスターの設計例、旧式の計測装置の有効な活用法など
【信号源とパルス処理】:その他のユニークな回路
※本記事は、2008年7月29日にEDN Japan臨時増刊として発刊した「珠玉の電気回路200選」に掲載されたものです。著者の所属や社名、部品の品番などは掲載当時の情報ですので、あらかじめご了承ください。
「珠玉の電気回路200選」:EDN Japanの回路アイデア寄稿コラム「Design Ideas」を1冊にまとめたもの。2001〜2008年に掲載された記事から200本を厳選し、5つのカテゴリーに分けて収録した。
Copyright © ITmedia, Inc. All Rights Reserved.