⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mod16ofdm.m

📁 802.16a协议物理层的matlab实现
💻 M
字号:
function mod16ofdm(modparams)
% mod16ofdm(modparams)
% 802.16a/D6+ OFDM modulator simulation
% modparams: structure of parameters passed in by GUI
%
% COMMERCIAL IN CONFIDENCE
% Copyright (c) Commsonic Ltd 2002

% Commsonic Ltd , St John's Innovation Centre, Cowley Road, 
% Cambridge CB4 0WS, England
% Tel/Fax +44 1223 871071


% ----Input source selection
switch modparams.input,
case 1,
   % random bytes
   NumBytes=modparams.length; %max 4095 ?
   rand('state',0);
   data=floor(256*rand(1,NumBytes));
   
case 2,
   % input data from file
   infid=fopen(modparams.infile,'r');
   if infid<0, error('unable to open tx data file'); end
   % we expect ascii file, CRLF delimited bytes
   [data,NumBytes]=fscanf(infid,'%i',Inf);
   data=data(:).';
   if NumBytes==0, warning('empty input file');end
   if NumBytes>4095,
      disp('input file too long, truncated to 4095 bytes'); %??? what limit
      NumBytes=4095;
      data=data(1:4095);
   end
   
case 3,
   NumBytes=35;
   % Hex array of test data (p159 of 802.16aD6)
   hdata=['45';'29';'c4';'79';'ad';'0f';'55';'28';'ad';'87';'b5';'76';'1a';'9c';'80';'50';'45';'1b';'9f';'d9';'2a';...
         '88';'95';'eb';'ae';'b5';'2e';'03';'4f';'09';'14';'69';'58';'0a';'5d'];
   data=hex2dec(hdata)';
otherwise,
   error('Unsupported input index');
end

if modparams.test
   tdfid=fopen(modparams.debugfile,'w');
end

opfid = fopen(modparams.outfile, 'w');
if opfid < 0
   error('unable to open tx data file');
end


DIUC=0;
IUC=[DIUC modparams.UIUC];

RateID=modparams.RateID-1;

switch RateID,
case 0,
   Qam=4;
   CBSize=48;
   UBSize=24;
case 1,
   Qam=4;
   CBSize=48;
   UBSize=36;
case 2,
   Qam=16;
   CBSize=96;
   UBSize=48;
case 3,
   Qam=16;
   CBSize=96;
   UBSize=72;
case 4,
   Qam=64;
   CBSize=144;
   UBSize=96;
case 5,
   Qam=64;
   CBSize=144;
   UBSize=108;
otherwise,
   error('Unsupported RateID')
end

% Derived Parameters
OCRate=UBSize/CBSize;

if modparams.SubChanEnable,
   switch modparams.SubChanIndex,
   case {1,2,3,4},
      UBSize=UBSize/4;
      CBSize=CBSize/4;
      NumCarriers = 50;
   case {5,6},
      UBSize=UBSize/2;
      CBSize=CBSize/2;
      NumCarriers = 100;
   otherwise,
      error('Unsupported Sub-Channel Index');
   end
   
   CCRate=OCRate;
   
else
   % Conv Code Rates
   switch OCRate,
   case 1/2,
      CCRate=2/3;
   case 2/3,
      CCRate=3/4;
   case 3/4,
      CCRate=5/6;
   otherwise,
      error('Unsupported Code Rate Required');
   end
   NumCarriers = 200;
end

PwrK=sqrt(256*256/NumCarriers); %Correct Tx to unity pwr ~sqrt(Nfft)

% RS parameters
RSC_N=CBSize*CCRate;
RSC_K=UBSize;
RSC_T=(RSC_N-RSC_K)/2;


switch modparams.Guard,
case 1,
   Guard=1/32;
case 2,
   Guard=1/16;
case 3,
   Guard=1/8;
case 4,
   Guard=1/4;
otherwise,
   error('Unsupported Guard Index');
end


disp(sprintf('%i Qam, RateID=%i selected',Qam,RateID));

if modparams.test,
   if modparams.SubChanEnable,
      fprintf(tdfid,'Qam=%i\r\nRateID=%i\r\nDLUL=%i\r\nCCRate=%0.3f\r\nSubChan=%i\r\n',Qam,RateID,modparams.DLUL,CCRate,modparams.SubChanIndex);
   else
      fprintf(tdfid,'Qam=%i\r\nRateID=%i\r\nDLUL=%i\r\nCCRate=%0.3f\r\nRS=%i,%i,%i\r\n',Qam,RateID,modparams.DLUL,CCRate,RSC_N,RSC_K,RSC_T);
   end
   fprintf(tdfid,'UBSize=%i\r\nCBSize=%i\r\nSlot Offset=%i\r\nIUC=%i\r\n\r\n',UBSize,CBSize,modparams.slot,IUC(modparams.DLUL+1));
   
end

% QAM map
QamBits = log2(Qam);
map=get80216map(Qam);
NumDataCarriers=CBSize*8/QamBits;


% Calc pilot and data carrier indicies and preamble patterns
if modparams.SubChanEnable,
   [DataIndex, PilotIndex, LSf, LSt]=subchanpatterns(modparams.SubChanIndex);
else
   [SSf, LSf, SSt, LSt] = syncpatterns;
   CarrierIndex=[-100:100];
   PilotIndex=[-84 -60 -36 -12 12 36 60 84];
   DataIndex=CarrierIndex;
   DataIndex(PilotIndex+101)=[]; %remove the pilots
   DataIndex(97)=[]; %remove DC
end
% Assemble the preamble and write to file
TxData = [LSt(256*(0.5-Guard)+1:128) LSt LSt];
if modparams.DLUL==0,
   % if DL add the short sequences too
   TxData=[SSt(256*(0.25-Guard)+1:64) SSt SSt SSt SSt TxData];
end;
fwrite(opfid, [real(TxData);imag(TxData)]*PwrK, 'float32');


% Pad the data up to UBSize but leave 1 byte for 0x00 FEC tail
bytesover=mod(NumBytes,UBSize);
if bytesover~=(UBSize-1),
   padding=ones(1,UBSize-bytesover-1)*255;
   data=[data padding];
   NumBytes=length(data);
end
NumSyms = ceil(NumBytes/UBSize);
if (NumSyms*UBSize - NumBytes)~=1, error('Block padding error'); end


% get the full Wk pilot scrambling sequence
wpilotseq=pilotmodw(modparams.DLUL);
if (modparams.DLUL)==0,
   %DL
   pilotini=[1 0 1 0 0 0 1 1];
else
   %UL
   pilotbase=[1 0 1 0 1 1 1 1];
   % reduce number of pilots in sub-chan modes
   pilotini=pilotbase((PilotIndex+108)/24);
end
PilotVector=[1+0j -1+0j]*1; % {Wk=0,1}




%--- Calc and encode the FCH burst for a downlink
if modparams.DLUL==0,
   % FCH Burst for DL
   FCH(1)=RateID*16 + bitand(NumSyms,3840)/256;
   FCH(2)=bitand(NumSyms,255);
   FCH(3)=hcsenc(FCH(1:2));
   % Pad out to 24 bytes with 0xFF and a final 0x00
   FCH=[FCH 255*ones(1,23-length(FCH)) 0];
   
   % RS Encode the FCH with RS=32,24,4
   % pad the FCH with leading zeros to make a block of 239
   % RS Encoder is a 255,239,8
   rsdata=rsencode([zeros(1,239-24) FCH]);
   % lop off the leading zeros and the parity bytes we don't want.
   rsdata=rsdata(239-24+1:239+(4*2));
   % tx the parity bytes first then data
   rsdata=[rsdata(24+1:end) rsdata(1:24)];
   % change to bitstream data
   rsbindata = rsdata(ones(1,8),:);
   for k = 1:8
      bitmask = bitshift(1,8-k); % NOTE the MSB is used first
      rsbindata(k,:) = bitand(rsbindata(k,:), bitmask) ~= 0;
   end
   rsbindata = rsbindata(:).';
   
   % Conv Encode the FCH
   %init the shifter with zeros
   cin = zeros(1,6);
   [cdata,cout,mout]=convcode(rsbindata,cin,[],2/3);
   
   % Interleave FCH
   inter1=innerinterleave((cdata));
   inter2=outerinterleave(inter1,48*8,1);
   
   % divide up the bits over 192 data carriers
   symdata = reshape(inter2,2,192).'*pow2(1:-1:0).';
   
   % interleave space for pilots and null at DC
   fchmap=get80216map(4);
   DataSyms = zeros(1,201);
   DataSyms(DataIndex+101)=fchmap(symdata+1);
   
   % apply to the continuous pilot carriers and xor on the Wl sequence
   pilotdata = xor(pilotini,wpilotseq(1));
   
   % insert pilots into symbol
   DataSyms(PilotIndex+101) = PilotVector(pilotdata + 1);
   
   % expand to 256 pts and fft
   DataSyms256 = fftshift([zeros(1,28) DataSyms zeros(1,27)]);
   tmp = ifft(DataSyms256,256);
   
   % Add Cyclic Prefix
   TxData = [tmp(256*(1-Guard)+1:256) tmp(1:256)];
   
   % Write symbol to file at unity power
   fwrite(opfid, [real(TxData);imag(TxData)]*PwrK, 'float32');
   
   % Debug data output
   if modparams.test,
      fprintf(tdfid,'FCH Data\r\n');
      fprintf(tdfid,'%.2X ',FCH);
      fprintf(tdfid,'\r\n\r\nReed-Solomon Encoded FCH\r\n');
      fprintf(tdfid,'%.2X ',rsdata);
      fprintf(tdfid,'\r\n\r\nConvolutionally Coded FCH\r\n');
      fprintf(tdfid,'%.2X ',reshape(cdata,8,48).'*pow2(7:-1:0).');
      fprintf(tdfid,'\r\n\r\nInterleaved FCH\r\n');
      fprintf(tdfid,'%.2X ',reshape((inter2),8,48).'*pow2(7:-1:0).');
      fprintf(tdfid,'\r\n\r\nCarrier Mapped FCH (Index: I Q) x 1/sqrt(2)\r\n');
      for m=1:10:200
         fprintf(tdfid,'%i:%2.1f %2.1f, ',[(m-101:1:m-92).' real(DataSyms(m:m+9).')*sqrt(2),imag(DataSyms(m:m+9).')*sqrt(2)].');
         if m==191,
            fprintf(tdfid,'%i:%2.1f %2.1f, ',[100 real(DataSyms(201).')*sqrt(2),imag(DataSyms(201).')*sqrt(2)].');
         end
         fprintf(tdfid,'\r\n');
      end
      fprintf(tdfid,'\r\n\r\n');
   end
end


% ------- Scramble main data burst
if modparams.DLUL
   ScramIni=modparams.UIUC*2048 + bitand(modparams.slot,4095); %UL
else
   ScramIni=bin2dec('100101010000000'); %DL
end
% Get the full scrambling sequence for the burst and xor with data
ScramVec=scramvector(ScramIni,NumBytes*8);
sdata=bitxor(data,ScramVec);
% append final 0x00 flush byte
sdata=[sdata 0];


%---- Main OFDM symbol generation loop
for sym=1:NumSyms,
   
   % ------------ RS Encoder with bypass in SubChan mode
   if ~modparams.SubChanEnable,
      % pad the data with leading zeros to make a block of 239
      % RS Encoder is a 255,239,8
      rsdata=rsencode([zeros(1,239-UBSize) sdata((sym-1)*UBSize+1:sym*UBSize)]);
      % lop off the leading zeros and the parity bytes we don't want.
      rsdata=rsdata(239-UBSize+1:239+(RSC_T*2));
      % tx the parity bytes first then data
      rsdata=[rsdata(UBSize+1:end) rsdata(1:UBSize)];
   else
      % sub channel mode, bypass the RS
      rsdata=sdata((sym-1)*UBSize+1:sym*UBSize);
   end
   % change to bitstream data
   rsbindata = rsdata(ones(1,8),:);
   for k = 1:8
      bitmask = bitshift(1,8-k); % NOTE the MSB is used first
      rsbindata(k,:) = bitand(rsbindata(k,:), bitmask) ~= 0;
   end
   rsbindata = rsbindata(:).';
   
   
   
   % --------- Conv Encoder
   if sym==1,
      %init the shifter with zeros
      cin = zeros(1,6);
   else
      cin=cout;
   end
   %conv encode
   [cdata,cout,mout]=convcode(rsbindata,cin,[],CCRate);
   %dec2hex(reshape(cdata,8,CBSize).'*pow2(7:-1:0).')
   
   
   
   
   % ------------- Interleaver
   inter1=innerinterleave((cdata));
   inter2=outerinterleave(inter1,CBSize*8,QamBits/2);
   %dec2hex(reshape((inter2),8,CBSize).'*pow2(7:-1:0).')
   
   
   % divide up the bits over NumDataCarriers data carriers, normally 192
   symdata = reshape(inter2,QamBits,NumDataCarriers).'*pow2(QamBits-1:-1:0).';
   
   % interleave space for pilots and null at DC
   DataSyms = zeros(1,201);
   DataSyms(DataIndex+101)=map(symdata+1);
   
   % apply to the continuous pilot carriers and xor on the Wl sequence
   pilotdata = xor(pilotini,wpilotseq(sym));
   % insert pilots into symbol
   DataSyms(PilotIndex+101) = PilotVector(pilotdata + 1);
   
   
   % expand to 256 pts and fft
   DataSyms256 = fftshift([zeros(1,28) DataSyms zeros(1,27)]);
   tmp = ifft(DataSyms256,256);
   
   % Add Cyclic Prefix
   TxData = [tmp(256*(1-Guard)+1:256) tmp(1:256)];
   
   % Write symbol to file at unity power
   fwrite(opfid, [real(TxData);imag(TxData)]*PwrK, 'float32');
   
   
   % ---- Debug data output
   if modparams.test,
      fprintf(tdfid,'Test Data\r\n');
      if sym==NumSyms,
         fprintf(tdfid,'%.2X ',data((sym-1)*UBSize+1:sym*UBSize-1));
      else
         fprintf(tdfid,'%.2X ',data((sym-1)*UBSize+1:sym*UBSize));
      end
      fprintf(tdfid,'\r\n\r\nScrambled Data\r\n');
      fprintf(tdfid,'%.2X ',sdata((sym-1)*UBSize+1:sym*UBSize));
      fprintf(tdfid,'\r\n\r\nReed-Solomon Encoded Data\r\n');
      fprintf(tdfid,'%.2X ',rsdata);
      fprintf(tdfid,'\r\n\r\nConvolutionally Coded Data\r\n');
      fprintf(tdfid,'%.2X ',reshape(cdata,8,CBSize).'*pow2(7:-1:0).');
      fprintf(tdfid,'\r\n\r\nInterleaved Data\r\n');
      fprintf(tdfid,'%.2X ',reshape((inter2),8,CBSize).'*pow2(7:-1:0).');
      fprintf(tdfid,'\r\n\r\nCarrier Mapped Data (Index: I Q) x 1/sqrt(2)\r\n');
      for m=1:10:200
         fprintf(tdfid,'%i:%2.1f %2.1f, ',[(m-101:1:m-92).' real(DataSyms(m:m+9).')*sqrt(2),imag(DataSyms(m:m+9).')*sqrt(2)].');
         if m==191,
            fprintf(tdfid,'%i:%2.1f %2.1f, ',[100 real(DataSyms(201).')*sqrt(2),imag(DataSyms(201).')*sqrt(2)].');
         end
         fprintf(tdfid,'\r\n');
      end
      fprintf(tdfid,'\r\n\r\n');
   end
   
   
end
disp(sprintf('Transmitted %i FFT symbols\n',sym));


if modparams.test, fclose(tdfid); end

fclose(opfid);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -