ドキュメンテーション センター

  • 評価版
  • 製品アップデート

最新のリリースでは、このページがまだ翻訳されていません。 このページの最新版は英語でご覧になれます。

デジタル波形生成:正弦波の近似

この例では、組み込みシステムと、任意の波形生成機器におけるデジタル波形合成アプリケーションで使用する、正弦波データ テーブルの設計と評価に必要な主要手順のいくつかを示します。

デジタル信号プロセッサ (DSP) を使用したアナログ波形のリアルタイム直接デジタル合成と、デジタル アナログ コンバーター (DAC) に結合された組み込みプロセッサは、非常に小規模なシステムにおいても一般的になりつつあります。組み込みシステムや計測器で使用する波形の開発は、MATLAB と Simulink を緊密に統合することにより効率化できます。実際に Simulink Coder™ でターゲット ハードウェアに実装する前に、波形生成アルゴリズムと関連データをデスクトップで作成、解析することができます。

可能な場合、正弦波をデジタル的に最も正確に合成する方法は、omega*t を間隔 0 ~ 2*pi にたたみ込んで、フル精度の sin() 関数を直接各タイム ステップに対して計算することです。リアルタイム システムでは、一般的に計算負荷が大きすぎるため、このアプローチは使えません。この障壁を取り除く一般的な方法の 1 つは、0 から 2*pi、または半波形または 1/4 波形のデータで対称性を利用し、値のテーブルを使用して sin() 関数の動作を近似することです。

考慮すべきトレードオフとしては、アルゴリズムの効率性、必要なデータ ROM サイズ、実装の精度/スペクトル純度などがあります。独自の波形を設計する場合にも、同様の解析が必要です。テーブル データとルックアップ アルゴリズムだけでは、現場での性能は決まりません。その他に、リアルタイム クロックや、D/C コンバーターの精度や安定性への考慮も、全体の性能評価には必要です。Signal Processing Toolbox™ と DSP System Toolbox™ は、この分野において、MATLAB とSimulink の機能を補完します。

正弦波の動作を近似する別の一般的な方法は、CORDIC 近似を使用することです。CORDIC は、COordinate Rotation DIgital Computer の略語です。ギブンズ回転に基づく CORDIC アルゴリズムは、Shift-Add 反復演算のみを必要とするため、ハードウェア効率が最も優れたアルゴリズムの 1 つです。Fixed-Point Designer のライセンスがある場合は、fi_sin_cos_demofi_sin_cos_demo で CORDIC 近似に関するチュートリアル スタイルの例を見ることができます。

この例で使用されている歪解析は、次の書籍内で紹介されている原理に基づいています。"Digital Sine-Wave Synthesis Using the DSP56001/DSP56002", by Andreas Chrysafis, Motorola Inc. 1988

倍精度浮動小数点でのテーブルの作成

以下のコマンドを実行すると、256 点の正弦波が作成され、これらの点ではじめてサンプリングされたときに、線形内挿を使用してステップあたり 2.5 点のデルタでジャンプすることにより、その正弦波の全高調波ひずみが測定されます。正弦値を CORDIC 正弦近似に置き換えることで、同様の計算を行うことができます。周波数ベースの用途では、スペクトル純度の方がテーブル内の絶対誤差よりも重要な場合があります。

ファイル ssinthd.mssinthd.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' )
thd_ref_1 =

   4.8049e-32


thd_ref_2p5 =

   1.4176e-09


thd_ref_1c =

   1.2577e-30


thd_ref_2p5c =

   1.4176e-09

正弦波近似をモデルに付加

上記で設計した正弦波を Simulink モデルに含め、線形内挿を使用した場合と CORDIC 近似を使用した場合に、直接ルックアップとしてどのように機能するかを確認できます。このモデルでは、浮動小数点テーブルの出力が sin() 関数と比較されます。THD 計算から予想されるとおり、線形内挿は、sin() 関数と比較して直接テーブル ルックアップよりも誤差が小さくなります。CORDIC 近似は、線形内挿法に比べると誤差が小さくなります。このマージンは、CORDIC 正弦近似を計算するときの反復数に依存します。通常、反復数を増加すると、精度を向上させることができます (計算時間も増加します)。CORDIC 近似は、明示的な乗数を必要としないので、乗数が効率的でない場合や、ハードウェアに存在しない場合に使用されます。

sldemo_tonegen モデルを開くsldemo_tonegen モデルを開く

open_system('sldemo_tonegen');
set_param('sldemo_tonegen', 'StopFcn','');
sim('sldemo_tonegen');
currentFig = figure('Color',[1,1,1]);
subplot(3,1,1), plot(tonegenOut.time, tonegenOut.signals(1).values); grid
title('Difference between direct look-up and reference signal');
subplot(3,1,2), plot(tonegenOut.time, tonegenOut.signals(2).values); grid
title('Difference between interpolated look-up and reference signal');
subplot(3,1,3), plot(tonegenOut.time, tonegenOut.signals(3).values); grid
title('Difference between CORDIC sine and reference signal');

波形精度についての詳しい考察

シミュレーション時間の 4.8 ~ 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')
thd_direct1 =

   2.6423e-15


thd_direct2 =

   2.8660e-15


thd_direct3 =

   2.6423e-15


thd_linterp_2p5 =

   1.4175e-09

さまざまなテーブルと方法の結果の比較

ステップあたり 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')
thd_double_direct =

   4.7061e-05


thd_sfrac24_direct =

   4.7061e-05


thd_double_linear =

   7.9741e-10


thd_sfrac24_linear =

   8.1751e-10

事前設定された Sine Wave ブロックの使用

Simulink には、連続モードと離散モードの Sine Wave ソース ブロックに加え、正弦と余弦の対称性を利用する線形内挿ルックアップ テーブルを使用して関数近似を実装する固定小数点正弦および余弦関数ブロックもあります。例 sldemo_tonegen_fixpt では、サンプリングした正弦波ソースを基準信号として使用し、内挿を使用した場合と使用しない場合のルックアップ テーブルおよび固定小数点データ型の CORDIC 正弦近似と比較しています。

sldemo_tonegen_fixpt モデルを開くsldemo_tonegen_fixpt モデルを開く

open_system('sldemo_tonegen_fixpt');
set_param('sldemo_tonegen_fixpt', 'StopFcn','');
sim('sldemo_tonegen_fixpt');
figure('Color',[1,1,1]);
subplot(3,1,1), plot(tonegenOut.time, tonegenOut.signals(1).values); grid
title('Difference between direct look-up and reference signal');
subplot(3,1,2), plot(tonegenOut.time, tonegenOut.signals(2).values); grid
title('Difference between interpolated look-up and reference signal');
subplot(3,1,3), plot(tonegenOut.time, 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(tonegenOut.time, tonegenOut.signals(4).values); grid
title('Difference between time based sin() and reference signal');

直接ルックアップと線形内挿の動作の考察

ファイル sldemo_sweeptable_thd.msldemo_sweeptable_thd.m によって実行される固定小数点テーブルの全周波数スイープについて考えた方が、この設計の動作をより深く理解できるでしょう。24 ビットの分数固定小数点テーブルの全高調波ひずみは、ステップ サイズごとに測定され、一度に D 点進みます。ここで D は、1 から N/2 まで 0.25 点ごとに増加する数字です。N は この例では 256 点であり、1、2、2.5、3 の場合については既に上記で済んでいます。周波数は離散であるため、サンプルレートの関数です。

プロット内のひずみ動作のモードに注意してください。これらは常識的な認識と一致し、テーブルから 1 点で正確に取得する場合、誤差は最小です。線形内挿では、点と点の間の直接ルックアップの場合よりも誤差が小さくなります。直感的に理解しにくいのは、ナイキスト周波数までの各モードの誤差が比較的一定であることです。

figure('Color',[1,1,1])
tic, sldemo_sweeptable_thd(24, 256), toc
Elapsed time is 0.996354 seconds.

次のステップ

この例をさらに掘り下げるには、異なるテーブル精度と要素カウントを試してみて、それぞれの影響を調べます。CORDIC 近似を使用して、異なる反復回数を試し、精度と計算時間に対する影響を確認します。Simulink Coder から可能な自動コード生成と Embedded Coder™ を使用した量産コード生成により、波形合成アルゴリズムのさまざまな実装オプションを調べることができます。Embedded Target 製品は、さまざまなリアルタイム プロセッサや DSP への直接接続を提供しています。たとえば、ターゲットのリアルタイム実行中に Simulink ブロック線図へ接続し直すことができます。Signal Processing Toolbox と DSP System Toolbox は、MATLAB および Simulink と連携して、広範囲なサンプル ベースおよびフレーム ベースの信号処理システムを設計および実装するために、事前にパッケージ化した機能を備えています。

bdclose('sldemo_tonegen');
bdclose('sldemo_tonegen_fixpt')
この情報は役に立ちましたか?