次の図は、2 つの信号データ チャネルをサポートするアプリケーションで、1 つを低帯域幅の 2 チャネルに分割し、もう 1 つは中断なしに動作を継続する必要があります。このような動的リコンフィギュレーションは、ワイヤレス アプリケーションでは一般的です。
この図では、最初のチャネルは LTE20 のデータをそのまま処理し、中央のチャネルは 2 つの LTE10 チャネルに動的に分割されています。carrier configuration RTP と示された制御パラメーターは、ブロック境界でデータ処理を分けるために使用されます。中央のチャネルが LTE20 チャネルとして動作している場合、11 タップのハーフバンド カーネルはバイパスされます。ただし、中央のチャネルの帯域幅を自身と、2 つの LTE10 チャネルを形成する 3 番目のチャネルとの間で分割する場合、データを混合する前に両方のチャネルに 3 段のフィルター チェーンが必要です。これは、11 タップのハーフバンド フィルターをフローに戻し、ミキサーをリコンフィギュレーションして、2 つではなく、3 つのデータストリームを処理するようにすることで実現できます。
次に、上記アプリケーションの最上位入力グラフの仕様を示します。
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® プロセッサによって、ランタイム パラメーターのアップデート/読み出しメカニズム で説明されている対話型またはスクリプト型のメカニズムを使用して駆動できます。これも、グラフ内に埋め込むことで、階層的に接続できます。