デジタル波形生成: 正弦波の近似
この例では、組み込みシステムと、任意の波形生成機器におけるデジタル波形合成アプリケーションで使用する、正弦波データ テーブルを設計および評価する方法について説明します。
小規模なシステムにおいても、デジタル アナログ コンバーター (DAC) に接続された組み込みプロセッサとデジタル信号プロセッサ (DSP) を使用したアナログ波形のリアルタイム直接デジタル合成を使用しています。MATLAB® および Simulink® を使用することで、実際に Simulink® Coder™ でターゲット ハードウェアに実装する前に、波形生成アルゴリズムと関連データを開発、解析することができます。
正弦波をデジタル的に最も正確に合成する方法は、omega*t
を間隔 0
~ 2*pi
に畳み込んで、フル精度の関数 sin
を直接各タイム ステップに対して計算することです。リアルタイム システムでは、一般的に計算負荷が大きすぎるため、このアプローチは使えません。別の方法として、値のテーブルを使用して、0
から 2*pi
、半波形、または 1/4 波形のデータから関数 sin の動作を近似できます。
2 つの方法のトレードオフとしては、アルゴリズムの効率性、必要なデータ ROM サイズ、実装の精度とスペクトル純度などがあります。独自の波形を設計する場合にも、同様の解析が必要です。テーブル データとルックアップ アルゴリズムだけでは、現場での性能は決まりません。全体の性能評価には、その他に、リアルタイム クロックや、デジタルからアナログへの変換の精度および安定性などについての考慮も必要です。Signal Processing Toolbox™ と DSP System Toolbox™ は、この分野において、MATLAB と Simulink の機能を補完します。
正弦波の動作を近似する別の方法は、CORDIC (COordinate Rotation DIgital Computer) 近似を使用することです。ギブンス回転に基づく CORDIC アルゴリズムは、Shift-Add 反復演算のみを必要とするため、ハードウェア効率が最も優れたアルゴリズムの 1 つです。
倍精度浮動小数点でのテーブルの作成
以下のコマンドを実行すると、256 点の正弦波が作成され、これらの点ではじめてサンプリングされたときに、線形内挿を使用してステップあたり 2.5
点のデルタでジャンプすることにより、その正弦波の全高調波ひずみが測定されます。正弦値を CORDIC 正弦近似に置き換えることで、同様の計算を行うことができます。周波数ベースの用途では、スペクトル純度の方がテーブル内の絶対誤差よりも重要な場合があります。
この例では、ファイル ssinthd.m
では、内挿あり/なしのデジタル正弦波生成の全高調波ひずみ (THD) を計算します。この THD
アルゴリズムは正確な結果を導くために、整数個の波に行われます。使用される波サイクルの数は A です。ステップ サイズ 'delta'
は A/B
です。A
波を横断するとテーブル内のすべての点に少なくとも 1 回はヒットします。これは、全サイクルにわたって平均 THD を正確に求めるために必要です。
THD の計算に使用する関係は以下のとおりです。
THD = (ET - EF) / ET,
ここで ET
= エネルギー総量、EF
= 基本エネルギーです。
ET
と EF
のエネルギー差異は、疑似エネルギーです。
N = 256; angle = 2*pi*(0:(N-1))/N; s = sin(angle)'; thd_ref_1 = ssinthd(s,1,N,1,'direct' ); thd_ref_2p5 = ssinthd(s,5/2,2*N,5,'linear' ); cs = cordicsin(angle,50)'; thd_ref_1c = ssinthd(cs,1,N,1,'direct' ); thd_ref_2p5c = ssinthd(cs,5/2,2*N,5,'linear' );
モデルでの正弦波近似の使用
設計した正弦波を Simulink モデルに含め、線形内挿を使用した場合と CORDIC 近似を使用した場合に、直接ルックアップとしてどのように機能するかを確認できます。このモデルでは、浮動小数点テーブルの出力が関数 sin
と比較されます。THD 計算から予想されるとおり、線形内挿は、関数 sin
と比較して直接テーブル ルックアップよりも誤差が小さくなります。CORDIC 近似は、線形内挿法に比べると誤差が小さくなります。このマージンは、CORDIC sin
近似を計算するときの反復数に依存します。通常、反復数を増加すると、精度を向上させることができます。CORDIC 近似は、明示的な乗数を必要としません。乗数が効率的でない場合や、ハードウェアに存在しない場合に使用されます。
sldemo_tonegen
モデルを開いてシミュレートします。
open_system('sldemo_tonegen'); set_param('sldemo_tonegen', 'StopFcn',''); out = sim('sldemo_tonegen');
シミュレーション出力をプロットします。
currentFig = figure('Color',[1,1,1]); subplot(3,1,1), plot(out.tonegenOut.time, out.tonegenOut.signals(1).values); grid title({'Difference between direct lookup', 'and reference signal'}); subplot(3,1,2), plot(out.tonegenOut.time, out.tonegenOut.signals(2).values); grid title({'Difference between interpolated lookup', 'and reference signal'}); subplot(3,1,3), plot(out.tonegenOut.time, out.tonegenOut.signals(3).values); grid title({'Difference between CORDIC sine', 'and reference signal'});
波形精度の検査
信号を調べると、アルゴリズムごとに異なる特性を確認できます。たとえば、シミュレーション時間の 4.5
~ 5.2
秒の信号にズームインします。
ax = get(currentFig,'Children'); set(ax(3),'xlim',[4.8, 5.2]); set(ax(2),'xlim',[4.8, 5.2]); set(ax(1),'xlim',[4.8, 5.2]);
固定小数点でのテーブルの実装
最も近い整数への丸めを使用して、浮動小数点テーブルを 24 ビットの分数に変換できます。新しいテーブルの全高調波ひずみを、直接ルックアップ モードでステップあたり 1、2、3 点でテストし、次に、固定小数点線形内挿でテストします。
bits = 24; is = num2fixpt(s,sfrac(bits),[],'Nearest','on'); thd_direct1 = ssinthd(is,1,N,1,'direct'); thd_direct2 = ssinthd(is,2,N,2,'direct'); thd_direct3 = ssinthd(is,3,N,3,'direct'); thd_linterp_2p5 = ssinthd(is,5/2,2*N,5,'fixptlinear');
結果の比較
ステップあたり 8.25
点のテーブル ステップ レート (33/4
) を選択し、直接モードと線形モードで倍精度および固定小数点テーブルをジャンプし、ゆがみ結果を比較します。
thd_double_direct = ssinthd(s,33/4,4*N,33,'direct'); thd_sfrac24_direct= ssinthd(is,33/4,4*N,33,'direct'); thd_double_linear = ssinthd( s,33/4,4*N,33,'linear'); thd_sfrac24_linear = ssinthd(is,33/4,4*N,33,'fixptlinear');
事前設定された Sine Wave ブロックの使用
Simulink には、連続モードと離散モードの Sine Wave ブロックに加え、正弦と余弦の 4 分の 1 波長の対称を利用する線形内挿ルックアップ テーブルを使用して関数近似を実装する固定小数点正弦および余弦関数ブロックもあります。モデル sldemo_tonegen_fixpt
では、サンプリングした正弦波ソースを基準信号として使用し、内挿を使用した場合と使用しない場合のルックアップ テーブルおよび固定小数点データ型の CORDIC 正弦近似と比較しています。
sldemo_tonegen_fixpt
モデルを開きます。
open_system('sldemo_tonegen_fixpt'); set_param('sldemo_tonegen_fixpt', 'StopFcn',''); out = sim('sldemo_tonegen_fixpt');
シミュレーション出力をプロットします。
figure('Color',[1,1,1]); subplot(3,1,1), plot(out.tonegenOut.time, out.tonegenOut.signals(1).values); grid title({'Difference between direct lookup', 'and reference signal'}); subplot(3,1,2), plot(out.tonegenOut.time, out.tonegenOut.signals(2).values); grid title({'Difference between interpolated lookup', 'and reference signal'}); subplot(3,1,3), plot(out.tonegenOut.time, out.tonegenOut.signals(3).values); grid title({'Difference between CORDIC sine', 'and reference signal'});
Clock 入力による正弦関数の使用
また、モデルでは正弦波ソース参照を関数 sin
と比較しています。この関数の入力角度 (ラジアン単位) は時間ベース、つまり Clock を使用して計算されます。Clock 入力が 2*pi
の周期間、関数 sin
から繰り返し可能な結果を返すという仮定をテストできます。次のプロットは、入力が時間ベースである場合に、関数 sin
で誤差が蓄積することを示しています。さらに、プロットはサンプリングした正弦波ソースを波形発生器として使用した方がより正確であることも示しています。
subplot(1,1,1), plot(out.tonegenOut.time, out.tonegenOut.signals(4).values); grid title({'Difference between time-based sin function', 'and reference signal'});
直接ルックアップと線形内挿の動作の考察
固定小数点テーブルの全周波数スイープを実行し、この設計の動作を理解するには、ファイル sldemo_sweeptable_thd.m を実行します。24 ビットの分数固定小数点テーブルの全高調波ひずみは、ステップ サイズごとに測定され、一度に D
点進みます。ここで D
は、1
から N/2
まで 0.25 点ごとに増加する数字です。N
はこの例では 256 点です。周波数は離散であるため、サンプルレートの関数です。
プロット内のひずみ動作のモードに注意してください。テーブルから 1 点で正確に取得する場合、誤差は最小です。線形内挿では、点と点の間の直接ルックアップの場合よりも誤差が小さくなります。ただし、ナイキスト周波数までの各モードの誤差は比較的一定です。
figure('Color',[1,1,1]);
tic, sldemo_sweeptable_thd(24, 256), toc;
Elapsed time is 1.001418 seconds.
次のステップ
CORDIC 近似により、異なる反復回数を使用してこの例を実行し、精度と計算時間に対する影響を確認できます。Simulink Coder で可能な自動コード生成と Embedded Coder™ を使用した量産コード生成により、波形合成アルゴリズムのさまざまな実装オプションを試します。組み込みターゲット製品は、さまざまなリアルタイム プロセッサや DSP への直接接続を提供しています。たとえば、ターゲットのリアルタイム実行中に Simulink モデルへ接続し直すことができます。Signal Processing Toolbox と DSP System Toolbox は、MATLAB および Simulink と連携して、広範囲なサンプル ベースおよびフレーム ベースの信号処理システムを設計および実装するための機能を備えています。
参照
[1] Chrysafis, Andrea. "Digital Sine-Wave Synthesis Using the DSP56001/2." Motorola, 1988.
参考
Sine, Cosine | Sine Wave | Sine Wave Function
関連するトピック
- Simulink での CORDIC アルゴリズム (Fixed-Point Designer)
- 正弦関数のルックアップ テーブルの作成 (Fixed-Point Designer)