Main Content

このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。

Massive MIMO ハイブリッド ビームフォーミング

この例では、マルチユーザー システムおよびシングルユーザー システムの両方の手法を使用して、Massive MIMO 通信システムの送信端でハイブリッド ビームフォーミングを使用する方法を示します。この例では、フル チャネル サウンディングを使用して、送信機のチャネル状態情報を特定します。マルチユーザー システムとシングルユーザー システムに異なる手法を使用して、必要なプリコーディングをデジタル ベースバンドとアナログ RF 成分に分割します。この例では、EVM および BER 通信システムの性能指数を計算し、簡易なオールデジタル受信機によって再生された信号と複数の送信データ ストリームを比較します。

この例では、散乱ベースの空間チャネル手法により、送信/受信の空間的位置とアンテナ パターンをモデル化します。リンクの検証のために、より単純で静的なフラット MIMO チャネルも提供されます。

はじめに

ますます増加する高いデータ レートとユーザー容量の需要によって、利用可能なスペクトルのより効率的な利用に対するニーズが高まっています。マルチユーザー MIMO (MU-MIMO) では、同じ時間-周波数リソースを使用して基地局 (BS) の送信機が複数の移動局 (MS) の受信機と同時に通信できるようにすることによってスペクトル効率を改善します。Massive MIMO では、BS アンテナ素子数を数十から数百の規模にできるため、セル内のデータ ストリーム数も大きな値に増やすことができます。

5G 無線システムでは、ミリメートル波 (mmWave) 帯を使用してより広い帯域を活用できます。5G システムでは、大規模アンテナ アレイも展開し、mmWave 帯における著しい伝播損失を軽減します。

mmWave 帯域の波長は小さいため、同じ物理的寸法のアレイに、より多くの素子を含めることができます。各アンテナ素子に 1 つの送信-受信 (TR) モジュール (RF チェーン) を設けることになるため、コストがかなり高くなります。ハイブリッド トランシーバーは、RF ではアナログ ビームフォーマー、ベースバンド領域ではデジタル ビームフォーマーの組み合わせを使用するので、RF チェーンが送信素子数よりも少なく、現実的な解決策です [ 1 ]。

ハイブリッド ビームフォーミング

ハイブリッド ビームフォーミング (ハイブリッド プリコーディングとも呼ばれる) は、Massive MIMO アンテナ アレイを低電力かつ費用対効果の高い方法で使用できるようにする手法です [ 1 ]。従来のアンテナ アレイでは、各データ ストリームを送受信するために各アンテナに専用の RF チェーンが必要になりますが、ハイブリッド プリコーディングでは、各ストリームに専用の RF チェーンが必要になります。これにより、RF チェーンの数が大幅に減り、コストと電力が削減されます。各チェーンのアナログ出力は、大規模なアンテナ アレイに接続されたアナログ RF ゲインとフェーズ シフターのネットワーク (Frf と表記されたアナログ RF ビームフォーマー) に結合されます。ここで、アンテナ数 >> ストリーム数です。これらのアナログ ユニットは重みをすぐに変更することができません。しかし、計算された RF 重みは主に受信機の空間位置によって決定されるため、時間の経過とともにゆっくりと変化します。デジタル ベースバンド プリコーディング重み (Fbb と表記) は、小規模なマルチパス効果によりシンボルごとに変化する場合があります。また、周波数選択性フェージングを考慮するためにサブキャリアごとに変化する場合もあります。

この例では、シングルユーザーまたはマルチユーザーの MIMO-OFDM システムを使用し、送信端における必要なプリコーディングのデジタル ベースバンドと RF アナログ成分への分割を示します。この例では、シングルユーザー システムには直交マッチング追跡 (OMP) アルゴリズム [ 3 ] を、マルチユーザー システムにはジョイント空間分割多重 (JSDM) 手法 [ 24 ] を使用して、選択したシステム構成のデジタル ベースバンド Fbb と RF アナログ Frf プリコーディングの重みを決定します。MIMO-OFDM Precoding with Phased Arrays (Phased Array System Toolbox)の例で示したシステムを基に、この例では送信端のプリコーディング行列の公式化と、それらの MIMO-OFDM システムへの適用を示します。

ジョイント空間分割多重を使用したバーチャル セクター化

JSDM は、セル内のユーザーの空間クラスタリングを利用し、これらのクラスターをグループ化し、RF アナログ ビームフォーミングを使用してこれらのグループにバーチャル セクターを作成します。グループの空間共分散行列は、基地局アンテナ アレイに対するグループの空間方向に関連付けられます。これらの行列は、サウンディング信号から生成されたチャネル推定を使用して計算され、これらの行列からアナログ RF ビームが導出されます。これらのビームは送信エネルギーをそれぞれのグループに集中させ、グループ間の干渉を最小限に抑えます。

ビームが形成されると、デジタル プリコーディング重みが計算され、各グループ内のユーザーを直交化するために使用されます。それらのプリコーディング重みは、RF チェーンの出力 (アンテナ アレイの出力ではない) が示す "実効チャネル" のユーザーのチャネル状態情報 (CSI) に基づいています。このようなビームベースの測定は 5G システムで行われます。

アナログ RF ゲインとフェーズ シフターはアンテナで実行されるため、RF 重みはすべてのサブキャリアに適用されることになります。しかし、デジタル プリコーディング重みはサブキャリアごとに適用できます。この例では、各サブキャリアは、サブキャリアの CSI から計算されたデジタル プリコーディング重みを適用します。

s = rng(67);                  % Set RNG state for repeatability

システム パラメーター

例として、システム パラメーターを定義します。これらのパラメーターを変更するとシステムへの影響を調べることができます。

prm.fc = 28e9;               % 28 GHz system
prm.chanSRate = 100e6;       % Channel sampling rate, 100 Msps
prm.ChanType = 'Scattering'; % Channel options: 'Scattering', 'MIMO'
prm.NFig = 8;                % Noise figure (increase to worsen, 5-10 dB)
prm.nRays = 500;             % Number of rays for Frf, Fbb partitioning

% Each user has the same modulation
prm.bitsPerSubCarrier = 4;          % 2: QPSK, 4: 16QAM, 6: 64QAM, 8: 256QAM
prm.numDataSymbols = 10;            % Number of OFDM data symbols

% Create a vector of users where each element is a user and the value of
% that element describes the number of independent data streams. For a
% single user case, make this a scalar value.
prm.numSTSVec = [4 3 2 4 3];        % Number of independent data streams per user
prm.numSTS    = sum(prm.numSTSVec); % Must be a power of 2
prm.numTx     = prm.numSTS*8;       % Number of BS transmit antennas (power of 2)

各ユーザーをグループに割り当てます。ユーザーは各グループの中心付近にランダムに配置されます。単一ユーザーのユース ケースの場合、グループ化の概念は適用されず、ユーザーがランダムにセルに配置されます。

% The group assignments for the active users must be in ascending
% order. The default setting matches the group diagram above; there are two
% groups of users with the first three users assigned to group one and the
% last two users assigned to group two.
prm.groups    = [1 1 1 2 2];  % Describes which users are in which groups

シミュレーションには 2 つの JSDM オプションを使用できます。このオプションは、デジタル プリコーディング重みを計算する方法を決定します。RF アナログ重みは、選択されたオプションとは無関係に計算されます。

  • 'JGP': ジョイント グループ処理 (JGP) によるジョイント空間分割多重。MIMO ストリームは、すべてのユーザーのチャネル推定値の CSI フィードバックに基づいてプリコーディングされます。

  • 'PGP': グループごとの処理 (PGP) によるジョイント空間分割多重。これは特殊なケースであり、ユーザーの CSI フィードバックが、ユーザーのグループに送信されたストリームの CSI のみを返送するように省略され、CSI フィードバック用に予約されていた利用可能帯域幅が増加します。プリコーディングが各グループのストリームでのみ実行されるため、パフォーマンスは JGP よりわずかに劣ります。また、送信ストリームの数に対するチャネルのランクの影響を特に受けやすくなります。

prm.jsdmType = 'JGP'; % JSDM option: 'JGP' or 'PGP' (for multi-user simulation)

MIMO チャネルは位置を認識しないため、ChanType パラメーター フィールドを使用して MIMO チャネルを選択すると、JSDM のパフォーマンスが最適ではなくなることに注意してください。散乱チャネルを使用する場合は、各グループに追加の受信機を追加して、グループの観察された共分散行列のチャネル ランクを改善し、各グループに送信されるストリームの数をサポートします。これらの受信機はアクティブにデータを受信していませんが、グループの一部として基地局に接続されていると見なされます。

prm.numSTSVecAll = prm.numSTSVec;       % Number of independent data streams per user
prm.numUsers  = length(prm.numSTSVec);  % Number of active users
prm.numGroups = max(prm.groups);  % Number of groups
numGroups = prm.numGroups;
if strcmp(prm.ChanType,'Scattering')
    for g = 1:numGroups
        prm.groups(prm.numUsers+g) = g;
        prm.numSTSVecAll(prm.numUsers+g) = 2;
    end
end

% Define the center of each group's range, azimuth, and elevation,
% assuming the BS is at the origin.
%   Angles specified as [azimuth;elevation] degrees
% Note: the number of columns must equal the number of groups
maxRange = 700;            % all MSs within 700 meters of BS
groupRanges = randi([1 maxRange],1,numGroups);
groupAzimuth = -60 + 60/(numGroups+1) + ...
    (120-(120/(numGroups+1)))/(numGroups-1) * (0:numGroups-1);
groupElevations = randi([-10 10],1,numGroups);

% Position mobile units
prm.numConnectedUsers = length(prm.numSTSVecAll); % Number of connected users
if prm.numUsers == 1
    % For a single user, randomly place the user
    % MS positions: assumes BS at origin
    %   Angles specified as [azimuth;elevation] degrees
    %   az in range [-180 180], el in range [-90 90], e.g. [45;0]
    prm.mobileRanges = randi([1 maxRange],1,prm.numConnectedUsers);
    prm.mobileAngles = [rand(1,prm.numConnectedUsers)*360-180; ...
                        rand(1,prm.numConnectedUsers)*180-90];
else
    % For multiple users, randomly place the users within their assigned
    % group locations
    prm.mobileRanges = zeros(prm.numConnectedUsers,1);
    prm.mobileAngles = zeros(2,prm.numConnectedUsers);
    for uIdx = 1:prm.numConnectedUsers
        g = prm.groups(uIdx);
        prm.mobileRanges(uIdx)   = groupRanges(g) + 30*rand(1);
        prm.mobileAngles(:,uIdx) = ...
            [groupAzimuth(g)+3*rand(1); groupElevations(g)+3*rand(1)];
    end
end

システムに使用する OFDM 変調パラメーターを定義します。

prm.FFTLength = 256;
prm.CyclicPrefixLength = 64;
prm.numCarriers = 234;
prm.NullCarrierIndices = [1:7 129 256-5:256]'; % Guards and DC
prm.PilotCarrierIndices = [26 54 90 118 140 168 204 232]';
nonDataIdx = [prm.NullCarrierIndices; prm.PilotCarrierIndices];
prm.CarriersLocations = setdiff((1:prm.FFTLength)', sort(nonDataIdx));
prm.numRx = prm.numSTSVecAll;   % Number of receive antennas, per connected user

numSTS = prm.numSTS;
numTx = prm.numTx;
numRx = prm.numRx;
numSTSVec = prm.numSTSVec;
numUsers = prm.numUsers;
codeRate = 1/3;             % same code rate per user
numTails = 6;               % number of termination tail bits
prm.numFrmBits = numSTSVec.*(prm.numDataSymbols*prm.numCarriers* ...
                 prm.bitsPerSubCarrier*codeRate)-numTails;
prm.modMode = 2^prm.bitsPerSubCarrier; % Modulation order
% Account for channel filter delay
numPadSym = 3;          % number of symbols to zero pad
prm.numPadZeros = numPadSym*(prm.FFTLength+prm.CyclicPrefixLength);

送信および受信アレイとシステムの位置的パラメーターを定義します。

prm.cLight = physconst('LightSpeed');
prm.lambda = prm.cLight/prm.fc;

% Get transmit and receive array information
prm.numSTSVec = prm.numSTSVecAll; % get array info for all connected users
prm.numUsers = prm.numConnectedUsers;
[isTxURA,expFactorTx,isRxURA,expFactorRx] = helperArrayInfo(prm,true);
prm.numSTSVec = numSTSVec;             % restore parameters to active users
prm.numUsers = numUsers;

% Transmit antenna array definition
%   Array locations and angles
prm.posTx = [0;0;0];       % BS/Transmit array position, [x;y;z], meters
if isTxURA
    % Uniform Rectangular array
    txarray = phased.PartitionedArray(...
        'Array',phased.URA([expFactorTx numSTS],0.5*prm.lambda),...
        'SubarraySelection',ones(numSTS,numTx),'SubarraySteering','Custom');
else
    % Uniform Linear array
    txarray = phased.ULA(numTx, 'ElementSpacing',0.5*prm.lambda, ...
        'Element',phased.IsotropicAntennaElement('BackBaffled',false));
end
prm.posTxElem = getElementPosition(txarray)/prm.lambda;

spLoss = zeros(prm.numConnectedUsers,1);
prm.posRx = zeros(3,prm.numConnectedUsers);
for uIdx = 1:prm.numConnectedUsers

    % Receive arrays
    if isRxURA(uIdx)
        % Uniform Rectangular array
        rxarray = phased.PartitionedArray(...
            'Array',phased.URA([expFactorRx(uIdx) numRx(uIdx)], ...
            0.5*prm.lambda),'SubarraySelection',ones(numRx(uIdx), ...
            numRx(uIdx)),'SubarraySteering','Custom');
        prm.posRxElem = getElementPosition(rxarray)/prm.lambda;
    else
        if numRx(uIdx)>1
            % Uniform Linear array
            rxarray = phased.ULA(numRx(uIdx), ...
                'ElementSpacing',0.5*prm.lambda, ...
                'Element',phased.IsotropicAntennaElement);
            prm.posRxElem = getElementPosition(rxarray)/prm.lambda;
        else
            rxarray = phased.IsotropicAntennaElement;
            prm.posRxElem = [0; 0; 0]; % LCS
        end
    end

    % Mobile positions
    [xRx,yRx,zRx] = sph2cart(deg2rad(prm.mobileAngles(1,uIdx)), ...
                             deg2rad(prm.mobileAngles(2,uIdx)), ...
                             prm.mobileRanges(uIdx));
    prm.posRx(:,uIdx) = [xRx;yRx;zRx];
    [toRxRange,toRxAng] = rangeangle(prm.posTx,prm.posRx(:,uIdx));
    spLoss(uIdx) = fspl(toRxRange,prm.lambda);
end

チャネル状態情報

空間的に多重化されたシステムの場合、送信機でのチャネル情報を利用できることで、対象の方向とチャネルにおける信号エネルギーを最大化するためのプリコーディングの適用が可能になります。チャネルがゆっくり変化するという仮定の下で、これはチャネルを最初にサウンディングすることによって容易になります。BS は、MS 受信機がチャネルを推定するために使用する基準伝送を用いて、チャネルをサウンディングします。MS は、後続のデータ送信に必要なプリコーディングの計算のために、チャネル推定情報を BS に送り返します。

次の図は、モデル化されたチャネル サウンディングの処理を示します。

選択した MIMO システムの場合、プリアンブル信号がすべての送信アンテナ素子全体から送信され、チャネルを調整する受信機で処理されます。受信機アンテナ素子は、すべてのリンクに対して事前増幅、OFDM 復調、および周波数領域チャネル推定を実行します。

% Generate the preamble signal
prm.numSTS = numTx;             % set to numTx to sound out all channels
preambleSig = helperGenPreamble(prm);

% Transmit preamble over channel
prm.numSTS = numSTS;            % keep same array config for channel
prm.numUsers = prm.numConnectedUsers; % transmit sounding to all connected users
prm.numSTSVec = prm.numSTSVecAll; % transmit sounding to all connected users
[rxPreSig,chanDelay] = helperApplyMUChannel(preambleSig,prm,spLoss);
prm.numUsers = numUsers;
prm.numSTSVec = numSTSVec;

% Channel state information feedback
hDp = cell(prm.numConnectedUsers,1);
prm.numSTS = numTx;             % set to numTx to estimate all links
for uIdx = 1:prm.numConnectedUsers

    % Front-end amplifier gain and thermal noise
    rxPreAmp = phased.ReceiverPreamp( ...
        'Gain',spLoss(uIdx), ...    % account for path loss
        'NoiseFigure',prm.NFig,'ReferenceTemperature',290, ...
        'SampleRate',prm.chanSRate);
    rxPreSigAmp = rxPreAmp(rxPreSig{uIdx});
    %   scale power for used sub-carriers
    rxPreSigAmp = rxPreSigAmp * (sqrt(prm.FFTLength - ...
        length(prm.NullCarrierIndices))/prm.FFTLength);

    % OFDM demodulation
    rxOFDM = ofdmdemod(rxPreSigAmp(chanDelay(uIdx)+1: ...
        end-(prm.numPadZeros-chanDelay(uIdx)),:),prm.FFTLength, ...
        prm.CyclicPrefixLength,prm.CyclicPrefixLength, ...
        prm.NullCarrierIndices,prm.PilotCarrierIndices);

    % Channel estimation from preamble
    %       numCarr, numTx, numRx
    hDp{uIdx} = helperMIMOChannelEstimate(rxOFDM(:,1:numTx,:),prm);

end
prm.numSTS = numSTS;                 % revert back for data transmission
prm.numRx  = prm.numRx(1:numUsers);  % set numRx to number of active users

シングルユーザー システムでは、OMP 分割アルゴリズムは、アレイ応答ベクトル At の影響を受けます。理想的には、これらの応答ベクトルがチャネルから見えるすべての分布点を構成します。しかしこれらは、実際のシステムやチャネルの実現の場合には不明であるため、可能な限り多くの分布点をカバーするために 3 次元空間内の波の無作為な集合が使用されます。prm.nRays パラメーターは、波の数を指定します。

マルチユーザー システムの場合、JSDM アルゴリズムでは、ブロック対角化法 [ 5 ] に基づいて RF ビームフォーマーの重みを計算するために、各グループから空間共分散を計算する必要があります。各 MS からチャネル推定がフィード バックされ、BS がプリコーディングの重みを決定するために使用されます。この例では、量子化または実装遅延のない完全なフィードバックを想定しています。実効チャネルは RF ビームフォーマーの重みと CSI から計算され、その後デジタル ベースバンド事前コーダーの重みが計算されます。

% Calculate the hybrid weights on the transmit side
if numUsers==1
    % Single-user OMP
    %   Spread rays in [az;el]=[-180:180;-90:90] 3D space, equal spacing
    %   txang = [-180:360/prm.nRays:180; -90:180/prm.nRays:90];
    txang = [rand(1,prm.nRays)*360-180;rand(1,prm.nRays)*180-90]; % random
    At = steervec(prm.posTxElem,txang);
    AtExp = complex(zeros(prm.numCarriers,size(At,1),size(At,2)));
    for carrIdx = 1:prm.numCarriers
        AtExp(carrIdx,:,:) = At; % same for all sub-carriers
    end

    % Orthogonal matching pursuit hybrid weights
    [Fbb,Frf] = omphybweights(hDp{1},numSTS,numSTS,AtExp);

    v = Fbb;    % set the baseband precoder (Fbb)
    % Frf is same across subcarriers for flat channels
    mFrf = permute(mean(Frf,1),[2 3 1]);

else
    % Multi-user Joint Spatial Division Multiplexing

    % Get number of streams per group
    prm.numSTSGroupVec = zeros(1,numGroups);
    for g = 1:numGroups
        prm.numSTSGroupVec(g) = sum(prm.numSTSVecAll(prm.groups(1:prm.numUsers)==g));
    end

    % Get Rg (group covariances)
    % Note that there is only one R per group (not per user). It is up to the
    % caller to determine how this autocorrelation matrix is obtained from the
    % group.
    hcov = helperGetCovariance(hDp,prm);

    % Calculate the analog beamformer weights
    Bg = jsdmrfweights(hcov,prm.numSTSGroupVec);

    % Pack beamformer weights into a precoding array
    mFrf = cat(1,Bg{:});

    % Calculate (predict) the effective channel response for each user from
    % a beamformed sounding signal
    hEff = helperGetHeff(hDp,mFrf,prm);

    % Get the digital (baseband) weights
    Fbb = jsdmbbweights(hEff,prm.numSTSGroupVec,Bg);

    if strcmp(prm.jsdmType,'PGP')
        % Pack the per group CSI into a matrix (block diagonal) for PGP
        v = zeros(prm.numCarriers,sum(numSTSVec),sum(numSTSVec));
        for g = 1:prm.numGroups
            stsIdx = sum(prm.numSTSGroupVec(1:g-1))+(1:prm.numSTSGroupVec(g));
            v(:,stsIdx,stsIdx) = Fbb{g};  % Nst-by-Nsts-by-Nsts
        end
    else
        % JGP
        v = Fbb;
    end

end

送信アレイ パターンをプロットします。散乱チャネルの場合、ビームの方向はユーザーの空間的位置と密接に相関し、ビームの大きさはその方向に送信されるストリームの数と相関するはずです。

% Transmit array pattern plots
figure;
if isTxURA
    % URA element response for the first subcarrier
    pattern(txarray,prm.fc,-180:180,-90:90,'Type','efield', ...
            'ElementWeights',mFrf.'*squeeze(v(1,:,:)), ...
            'PropagationSpeed',prm.cLight);
else % ULA
    % Array response for first subcarrier
    wts = mFrf.'*squeeze(v(1,:,:));
    pattern(txarray,prm.fc,-180:180,-90:90,'Type','efield', ...
            'Weights',wts(:,1),'PropagationSpeed',prm.cLight);
end

モデル化された広帯域 OFDM システムでは、アナログの重み mFrf は複数のサブキャリアの平均の重みです。アレイ応答パターンは、より強いローブで表されるはっきりしたデータ ストリームを示します。これらのローブは、ビームフォーミングによって実現された広がりと分離可能性を示します。Introduction to Hybrid Beamforming (Phased Array System Toolbox)の例では、最適な完全デジタル方式のアプローチによって実現したパターンと、シングルユーザーのシステム向けに選択されたハイブリッド方式のアプローチで実現したパターンとの比較を行います。

データ送信

次に、システムのデータの送信機を構成します。この処理には、チャネル符号化、複素数シンボルへのビット マッピング、個別のデータ ストリームの複数の送信ストリームへの分割、送信ストリームのベースバンドプリコーディング、パイロット マッピングによる OFDM 変調、および使用されているすべての送信アンテナの RF アナログ ビームフォーミングが含まれます。

% Convolutional encoder
encoder = comm.ConvolutionalEncoder( ...
    'TrellisStructure',poly2trellis(7,[133 171 165]), ...
    'TerminationMethod','Terminated');

txDataBits = cell(numUsers, 1);
gridData = complex(zeros(prm.numCarriers,prm.numDataSymbols,numSTS));
for uIdx = 1:numUsers
    % Generate mapped symbols from bits per user
    txDataBits{uIdx} = randi([0,1],prm.numFrmBits(uIdx),1);
    encodedBits = encoder(txDataBits{uIdx});

    % Bits to QAM symbol mapping
    mappedSym = qammod(encodedBits,prm.modMode,'InputType','bit', ...
    'UnitAveragePower',true);

    % Map to layers: per user, per symbol, per data stream
    stsIdx = sum(numSTSVec(1:(uIdx-1)))+(1:numSTSVec(uIdx));
    gridData(:,:,stsIdx) = reshape(mappedSym,prm.numCarriers, ...
        prm.numDataSymbols,numSTSVec(uIdx));
end

% Apply precoding weights to the subcarriers, assuming perfect feedback
preData = complex(zeros(prm.numCarriers,prm.numDataSymbols,numSTS));
for symIdx = 1:prm.numDataSymbols
    for carrIdx = 1:prm.numCarriers
        Q = squeeze(v(carrIdx,:,:));
        normQ = Q * sqrt(numTx)/norm(Q,'fro');
        preData(carrIdx,symIdx,:) = squeeze(gridData(carrIdx,symIdx,:)).' ...
            * normQ;
    end
end

% Multi-antenna pilots
pilots = helperGenPilots(prm.numDataSymbols,numSTS);

% OFDM modulation of the data
txOFDM = ofdmmod(preData,prm.FFTLength,prm.CyclicPrefixLength,...
                 prm.NullCarrierIndices,prm.PilotCarrierIndices,pilots);
%   scale power for used sub-carriers
txOFDM = txOFDM * (prm.FFTLength/ ...
    sqrt((prm.FFTLength-length(prm.NullCarrierIndices))));

% Generate preamble with the feedback weights and prepend to data
preambleSigD = helperGenPreamble(prm,v);
txSigSTS = [preambleSigD;txOFDM];

% RF beamforming: Apply Frf to the digital signal
%   Each antenna element is connected to each data stream
txSig = txSigSTS*mFrf;

選択した、完全接続型の RF アーキテクチャでは、各アンテナ素子は、mFrf 行列の個々の列によって指定されるように prm.numSTS アナログ ゲインを使用します。

モデル化されているデータの送信と受信の処理を次に示します。

信号伝播

この例では、空間 MIMO チャネルのオプションと、検証目的用のより簡潔な静的フラット MIMO チャネルを提供します。

分布モデルでは、パラメーター化された分布点の数で単一バウンスのレイトレーシング近似を使用します。この例では、分布点の数は 50 に設定されています。'Scattering' オプションは、ワンリング モデル [ 6 ] と同様に、受信機を中心とした球体内にランダムに配置された分布点をモデル化します。

チャネル モデルでは、パス損失のモデル化、および見通し内 (LOS) と非 LOS の両方の伝播条件が許可されます。この例では、非 LOS 伝播と線形または矩形ジオメトリを持つ等方性アンテナ素子パターンを想定しています。

% Apply a spatially defined channel to the transmit signal
[rxSig,chanDelay] = helperApplyMUChannel(txSig,prm,spLoss,preambleSig);

サウンディングとデータ伝送の両方に同じチャネルが使用されます。データ送信は、期間がより長く、データ シンボル数のパラメーター prm.numDataSymbols によって制御されます。サウンディング段階と伝送段階の間のチャネルの変化は、プリアンブル信号をデータ信号の前に付加することによってモデル化されます。プリアンブルは、データ送信が有効な状態になるようチャネルを準備し、チャネル出力では無視されます。

マルチユーザー システムでは、ユーザーごとの独立したチャネルがモデル化されます。

受信増幅と信号再生

ユーザーごとにモデル化された受信機は、増幅によってパス損失を補正し、熱ノイズを追加します。送信機と同様に、MIMO-OFDM システムで使用される受信機には、OFDM 復調、MIMO イコライズ、QAM デマッピング、チャネル復号化など、多くの段階が含まれます。

hfig = figure('Name','Equalized symbol constellation per stream');
scFact = ((prm.FFTLength-length(prm.NullCarrierIndices))...
         /prm.FFTLength^2)/numTx;
nVar = noisepow(prm.chanSRate,prm.NFig,290)/scFact;
decoder = comm.ViterbiDecoder('InputFormat','Unquantized', ...
    'TrellisStructure',poly2trellis(7, [133 171 165]), ...
    'TerminationMethod','Terminated','OutputDataType','double');

for uIdx = 1:numUsers
    stsU = numSTSVec(uIdx);
    stsIdx = sum(numSTSVec(1:(uIdx-1)))+(1:stsU);

    % Front-end amplifier gain and thermal noise
    rxPreAmp = phased.ReceiverPreamp( ...
        'Gain',spLoss(uIdx), ...        % account for path loss
        'NoiseFigure',prm.NFig,'ReferenceTemperature',290, ...
        'SampleRate',prm.chanSRate);
    rxSigAmp = rxPreAmp(rxSig{uIdx});

    % Scale power for occupied sub-carriers
    rxSigAmp = rxSigAmp*(sqrt(prm.FFTLength-length(prm.NullCarrierIndices)) ...
        /prm.FFTLength);

    % OFDM demodulation
    rxOFDM = ofdmdemod(rxSigAmp(chanDelay(uIdx)+1: ...
        end-(prm.numPadZeros-chanDelay(uIdx)),:),prm.FFTLength, ...
        prm.CyclicPrefixLength,prm.CyclicPrefixLength, ...
        prm.NullCarrierIndices,prm.PilotCarrierIndices);

    % Channel estimation from the mapped preamble
    hD = helperMIMOChannelEstimate(rxOFDM(:,1:numSTS,:),prm);

    % MIMO equalization
    %   Index into streams for the user of interest
    [rxEq,CSI] = ofdmEqualize(rxOFDM(:,numSTS+1:end,:),hD(:,stsIdx,:),'Algorithm','zf');

    % Soft demodulation
    rxSymbs = rxEq(:)/sqrt(numTx);
    rxLLRBits = qamdemod(rxSymbs,prm.modMode,'UnitAveragePower',true, ...
        'OutputType','approxllr','NoiseVariance',nVar);

    % Apply CSI prior to decoding
    rxLLRtmp = reshape(rxLLRBits,prm.bitsPerSubCarrier,[], ...
        prm.numDataSymbols,stsU);
    csitmp = reshape(CSI,1,[],1,numSTSVec(uIdx));
    rxScaledLLR = rxLLRtmp.*csitmp;

    % Soft-input channel decoding
    rxDecoded = decoder(rxScaledLLR(:));

    % Decoded received bits
    rxBits = rxDecoded(1:prm.numFrmBits(uIdx));

    % Plot equalized symbols for all streams per user
    scaler = 2;
    for i = 1:stsU
        subplot(numUsers, max(numSTSVec), (uIdx-1)*max(numSTSVec)+i);
        plot(reshape(rxEq(:,:,i)/sqrt(numTx), [], 1), '.');
        axis square
        xlim(gca,[-scaler scaler]);
        ylim(gca,[-scaler scaler]);
        title(['U' num2str(uIdx) ', G' num2str(prm.groups(uIdx)) ', DS' num2str(i)]);
        grid on;
    end

    % Compute and display the EVM
    evm = comm.EVM('Normalization','Average constellation power', ...
        'ReferenceSignalSource','Estimated from reference constellation', ...
        'ReferenceConstellation', ...
        qammod((0:prm.modMode-1)',prm.modMode,'UnitAveragePower',1));
    rmsEVM = evm(rxSymbs);
    disp(['User ' num2str(uIdx) ' (Group ' num2str(prm.groups(uIdx)) ')']);
    disp(['  RMS EVM (%) = ' num2str(rmsEVM)]);

    % Compute and display bit error rate
    ber = comm.ErrorRate;
    measures = ber(txDataBits{uIdx},rxBits);
    fprintf('  BER = %.5f; No. of Bits = %d; No. of errors = %d\n', ...
        measures(1),measures(3),measures(2));
end
User 1 (Group 1)
  RMS EVM (%) = 0.00052493
  BER = 0.00000; No. of Bits = 12474; No. of errors = 0
User 2 (Group 1)
  RMS EVM (%) = 0.00052455
  BER = 0.00000; No. of Bits = 9354; No. of errors = 0
User 3 (Group 1)
  RMS EVM (%) = 0.00069415
  BER = 0.00000; No. of Bits = 6234; No. of errors = 0
User 4 (Group 2)
  RMS EVM (%) = 0.00079507
  BER = 0.00000; No. of Bits = 12474; No. of errors = 0
User 5 (Group 2)
  RMS EVM (%) = 0.00055637
  BER = 0.00000; No. of Bits = 9354; No. of errors = 0

モデル化された MIMO システムでは、イコライズされたシンボルの受信コンスタレーションを表示することで、受信の定性評価を提供します。実際のビット エラー レートは、ユーザーごとの実際の送信されたビットと受信および復号化されたビットを比較することで、定量的数値を提供します。

rng(s);         % restore RNG state

まとめとその他の調査

この例では、マルチユーザー MIMO-OFDM システムのハイブリッド ビームフォーミングの使用について示しています。これにより、いくつかのシステム全体のパラメーターを変更して、多様なチャネル モデル向けのさまざまなシステム構成を調べることができます。

構成可能なパラメーター セットには、ユーザーの数、ユーザーごとのデータ ストリームの数、送信/受信アンテナの素子の数、アレイの位置、チャネル モデルが含まれます。これらのパラメーターを調節することで、システム全体への個々のパラメーターの影響や組み合わせた場合の影響を調査できます。例として、次を変えてみます。

  • マルチユーザー システムとシングルユーザー システムを切り替えるための、ユーザー数、対応するデータ ストリーム (prm.numSTSVec)、および対応するグループ (prm.groups)、または

  • チャネル タイプ (prm.ChanType)、または

  • シングルユーザー システムに使用する光線の数 (prm.nRays)、または

  • マルチユーザー システムで使用される JSDM フィードバック タイプ (prm.jsdmType)、およびグループの場所 (groupAnglesgroupRanges)。

例で使用されている次の補助関数について調査します。

5G 通信システムで使用される JSDM を確認するには、TDD Reciprocity-Based PDSCH MU-MIMO Using SRS (5G Toolbox)の例を参照してください。

参考文献

  1. Molisch, A. F., et al. "Hybrid Beamforming for Massive MIMO: A Survey." IEEE® Communications Magazine, Vol. 55, No. 9, September 2017, pp. 134-141.

  2. Li Z., S. Han, and A. F. Molisch."Hybrid Beamforming Design for Millimeter-Wave Multi-User Massive MIMO Downlink."IEEE ICC 2016, Signal Processing for Communications Symposium.

  3. El Ayach, Oma, et al. "Spatially Sparse Precoding in Millimeter Wave MIMO Systems." IEEE Transactions on Wireless Communications, Vol. 13, No. 3, March 2014, pp. 1499-1513.

  4. Adhikary A., J. Nam, J-Y Ahn, and G. Caire."Joint Spatial Division and Multiplexing - The Large-Scale Array Regime."IEEE Transactions on Information Theory, Vol. 59, No. 10, October 2013, pp. 6441-6463.

  5. Spencer Q., A. Swindlehurst, M. Haardt, "Zero-Forcing Methods for Downlink Spatial Multiplexing in Multiuser MIMO Channels."IEEE Transactions on Signal Processing, Vol. 52, No. 2, February 2004, pp. 461-471.

  6. Shui, D. S., G. J. Foschini, M. J. Gans and J. M. Kahn."Fading Correlation and its Effect on the Capacity of Multielement Antenna Systems."IEEE Transactions on Communications, Vol. 48, No. 3, March 2000, pp. 502-513.