📄 mod16ofdm.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 + -