ランタイム パラメーターを使用するバイパス制御 - 2023.2 日本語

AI エンジン カーネルおよびグラフ プログラミング ガイド (UG1079)

Document ID
UG1079
Release Date
2023-12-04
Version
2023.2 日本語

次の図は、2 つの信号データ チャネルをサポートするアプリケーションで、1 つを低帯域幅の 2 チャネルに分割し、もう 1 つは中断なしに動作を継続する必要があります。このような動的リコンフィギュレーションは、ワイヤレス アプリケーションでは一般的です。

図 1. 2 つの LTE20 チャネルを 1 つの LTE20 と 2 つの LTE10 チャネルに動的にリコンフィギュレーション

この図では、最初のチャネルは LTE20 のデータをそのまま処理し、中央のチャネルは 2 つの LTE10 チャネルに動的に分割されています。carrier configuration RTP と示された制御パラメーターは、ブロック境界でデータ処理を分けるために使用されます。中央のチャネルが LTE20 チャネルとして動作している場合、11 タップのハーフバンド カーネルはバイパスされます。ただし、中央のチャネルの帯域幅を自身と、2 つの LTE10 チャネルを形成する 3 番目のチャネルとの間で分割する場合、データを混合する前に両方のチャネルに 3 段のフィルター チェーンが必要です。これは、11 タップのハーフバンド フィルターをフローに戻し、ミキサーをリコンフィギュレーションして、2 つではなく、3 つのデータストリームを処理するようにすることで実現できます。

ヒント: 遅延アライメント カーネルは、LTE20 と LTE10 の信号を混合する際にサンプル遅延のバランスを取るために必要であり、これら 2 つの信号を動的に切り替えるため、制御フローに含める必要があります。

次に、上記アプリケーションの最上位入力グラフの仕様を示します。

class lte_reconfig : public graph {
  private:
    kernel demux;
    kernel cf[3];
    kernel interp0[3];
    kernel interp1[2];
    bypass bphb11;
    kernel delay ;
    kernel delay_byp ;
    bypass bpdelay ;
    kernel mixer ;
  public:
    input_port in;
    input_port  fromPS;
    output_port out ;

    lte_reconfig() {
      // demux also handles the control
      demux = kernel::create(demultiplexor);
      connect<>(in, demux.in[0]);
      connect< parameter >(fromPS, demux.in[1]);

      runtime<ratio>(demux) = 0.1;
      source(demux) = "kernels/demux.cc";

      // instantiate all channel kernels
      for (int i=0;i<3;i++) {
        cf[i] = kernel::create(fir_89t_sym);
        source(cf[i]) = "kernels/fir_89t_sym.cc";
        runtime<ratio>(cf[i]) = 0.12;
      }
      for (int i=0;i<3;i++) {
        interp0[i] = kernel::create(fir_23t_sym_hb_2i);
        source(interp0[i]) = "kernels/hb23_2i.cc";
        runtime<ratio>(interp0[i]) = 0.1;
      }
      for (int i=0;i<2;i++) {
        interp1[i] = kernel::create(fir_11t_sym_hb_2i);
        source(interp1[i]) = "kernels/hb11_2i.cc";
        runtime<ratio>(interp1[i]) = 0.1;
      }
      bphb11 = bypass::create(interp1[0]);
      mixer =  kernel::create(mixer_dynamic);
      source(mixer) = "kernels/mixer_dynamic.cc";
      runtime<ratio>(mixer) = 0.4;
      delay =  kernel::create(sample_delay);
      source(delay) = "kernels/delay.cc";
      runtime<ratio>(delay) = 0.1;
      delay_byp =  kernel::create(sample_delay);
      source(delay_byp) = "kernels/delay.cc";
      runtime<ratio>(delay_byp) = 0.1;
      bpdelay = bypass::create(delay_byp) ;

      // Graph connections
      for (int i=0; i<3; i++) {
        connect<>(demux.out[i], cf[i].in[0]);
        connect< parameter >(demux.inout[i], cf[i].in[1]);
      }
      connect< parameter >(demux.inout[3], bphb11.bp);
      connect< parameter >(demux.inout[5], negate(bpdelay.bp)) ;
      for (int i=0;i<3;i++) {
        connect<>(cf[i].out[0], interp0[i].in[0]);
        connect< parameter >(cf[i].inout[0], interp0[i].in[1]);
      }
       // chan0 is LTE20 and is output right away
      connect<>(interp0[0].out[0], delay.in[0]);
      connect<>(delay.out[0], mixer.in[0]);
      // chan1 is LTE20/10 and uses bypass
      connect<>(interp0[1].out[0], bphb11.in[0]);
      connect< parameter >(interp0[1].inout[0], bphb11.in[1]);
      connect<>(bphb11.out[0], bpdelay.in[0]);
      connect<>(bpdelay.out[0], mixer.in[1]);
      // chan2 is LTE10 always
      connect<>(interp0[2].out[0], interp1[1].in[0]);
      connect< parameter >(interp0[2].inout[0], interp1[1].in[1]);
      connect<>(interp1[1].out[0], mixer.in[2]);
      //Mixer
      connect< parameter >(demux.inout[4], mixer.in[3]);
      connect<>(mixer.out[0], out);
    };
};

バイパス仕様は、バイパスされるカーネルに特別なエンキャプスレーターとしてコード化されています。バイパスのポート シグネチャは、カプセル化するカーネルのポートシグネチャと一致します。また、バイパスを制御するためのランタイム パラメーター (バイパスなしは 0 、バイパスありは 1) も受信します。前述のように、ネゲート関数を使用して制御を反転させることもできます。

このグラフのバイパス パラメーター ポートは通常のスカラー ランタイム パラメーターであり、ほかのカーネルまたは Arm® プロセッサによって、ランタイム パラメーターのアップデート/読み出しメカニズム で説明されている対話型またはスクリプト型のメカニズムを使用して駆動できます。これも、グラフ内に埋め込むことで、階層的に接続できます。