In this project, we create a link-level Monte-Carlo simulator. Then, we analyze the performance of convolutional codes over different wireless channels: additive white Gaussian noise(AWGN) and Rayleigh fading.
We use following blocks to implement our simulator: source generator, encoder/decoder, inter-leaver/deinterleaver, modulator/demodulator, and wireless channel.
Development tool: Matlab 2012a with Communication toolbox
function ObjectActive(Btn_handles, Line_handles, status) if strcmp(status , 'on') set(Btn_handles, 'Enable','on'); set(Line_handles, 'ForegroundColor','r'); elseif strcmp(status , 'off') set(Btn_handles, 'Enable','off'); set(Line_handles, 'ForegroundColor','k'); end %-------------------------------------------------------------------------- % Set the delay time of the objects in the Model Panel function ActionDelay(status, sec) if status == 1 pause(sec); elseif status == 0 pause(0); end %-------------------------------------------------------------------------- %Start Simulation function Btn_Simulation_Callback(hObject, eventdata, handles) % -----------------Start Initialization----------------- ObjectActive(handles.Btn_Model_Bernoulli, handles.Line1_1, 'off'); ObjectActive(handles.Btn_Model_Encoder, handles.Line1, 'off'); ObjectActive(handles.Btn_Model_Interleaver, handles.Line2, 'off'); ObjectActive(handles.Btn_Model_Modulator, handles.Line3, 'off'); ObjectActive(handles.Btn_Model_AWGN, handles.Line4, 'off'); ObjectActive(handles.Btn_Model_Rayleigh, handles.Line4, 'off'); ObjectActive(handles.Btn_Model_Demodulator, handles.Line5, 'off') ObjectActive(handles.Btn_Model_Deinterleaver, handles.Line6, 'off'); ObjectActive(handles.Btn_Model_Decoder, handles.Line7, 'off'); ObjectActive(handles.Btn_Model_ErrorRateCalc, handles.Line8, 'off'); dDelayTime = 0; DelayChecked = get(handles.CheckBox_Delay, 'value'); ActionDelay(DelayChecked, dDelayTime); global gFrameSize_F; FrameNum_K = str2double(get(handles.Edit_FrameNum,'string')); % Number of Frames (K) gFrameSize_F = str2double(get(handles.Edit_FrameSize,'string')); % Frame Size (F): bits ShiftBit_k = str2double(get(handles.Edit_NumBitShit,'string')); % Number of Bits Shifted (k): default k=1 EncoderOutputBit_N = str2double(get(handles.Edit_NumEncoderOutputBit,'string')); % Number of Encoder Output Bits (N) CodeRate_Rc = ShiftBit_k / EncoderOutputBit_N; % Code Rate (Rc=k/N) global gTimesOfOutputBits; gTimesOfOutputBits = EncoderOutputBit_N / ShiftBit_k; set(handles.Edit_CodeRate,'string', CodeRate_Rc); GeneratorPoly = str2num(get(handles.Edit_GeneratorPoly,'string')); MemoryNum_M = str2double(get(handles.Edit_NumMemory,'string')); % Number of Memory Elements (M) MatrixSize = size(GeneratorPoly); % Verify Trellis Structure if MatrixSize(1,2) ~= gTimesOfOutputBits set(handles.Edit_NumEncoderOutputBit, 'ForegroundColor','r'); set(handles.Edit_GeneratorPoly, 'ForegroundColor','r'); error_msg = 'Check the values of "Number of Encoder Output Bits" and "Generator Polynomials"'; msgbox(error_msg,'Error','error'); return; else set(handles.Edit_NumEncoderOutputBit, 'ForegroundColor','k'); set(handles.Edit_GeneratorPoly, 'ForegroundColor','k'); end SNR_dB = str2double(get(handles.Edit_SNR_dB,'string')); % AWGN Parameter: Signal to Noise Ratio (SNR) MobileSpeed_Low = str2double(get(handles.Edit_LowMobility,'string')); % Rayleigh Parameter: Mobile Speeds - Low (v) MobileSpeed_High = str2double(get(handles.Edit_HighMobility,'string')); % Rayleigh Parameter: Mobile Speeds - High (v) CarrierFrequency = str2double(get(handles.Edit_CarrierFrequency,'string')); % Rayleigh Parameter: Carrier Frequency (fc) BER_Target = str2double(get(handles.Edit_BER_Target,'string')); % Target BER SelectedVitebiDecisionType = (get(handles.ListBox_VitebiDecisionType,'Value')); % Viterbi Convolutional Encoder Parameter: Decision Type if SelectedVitebiDecisionType == 1 VitebiDecisionType = 'hard'; fprintf('Vitebi Decision Type: Hard Decision Decoding (HDD)\n'); elseif SelectedVitebiDecisionType == 2 VitebiDecisionType = 'soft'; fprintf('Vitebi Decision Type: Soft Decision Decoding (SDD)\n'); end SelectedWirelessChannelType = (get(handles.WirelessChannel_AWGN,'Value')); % Selecting Wireless Channel Type if SelectedWirelessChannelType == 1 WirelessChannelType = 1; fprintf('Wireless Channel Type: AWGN\n'); elseif SelectedWirelessChannelType == 0 WirelessChannelType = 2; fprintf('Wireless Channel Type: Rayleigh Fading\n'); SelectedRayleighSpectrumType = (get(handles.ListBox_SpectrumType,'Value')); % Rayleigh Parameter: Doppler Spectrum Type if SelectedRayleighSpectrumType == 1 RayleighSpectrumType = 'flat'; fprintf('Rayleigh Spectrum Type: Flat\n'); elseif SelectedRayleighSpectrumType == 2 RayleighSpectrumType = 'jakes'; fprintf('Rayleigh Spectrum Type: Jakes\n'); end end % -----------------End Initialization----------------- % Generate data and apply fading channel. M = 2; % DBPSK modulation order hModulator = comm.BPSKModulator; % Create a DPSK modulator hDemod = comm.BPSKDemodulator; % Create a DPSK demodulator Bernoulli = randi([0 1],gFrameSize_F,1); dpskSig = step(hModulator, Bernoulli); % DPSK modulate the signal chan = rayleighchan(1/10000,100); fadedSig = filter(chan,dpskSig); % Apply the channel effects % Compute error rate for different values of SNR. SNR = 0:2:20; % Range of SNR values, in dB. numSNR = length(SNR); berVec = zeros(3, numSNR); % Create an AWGNChannel and ErrorRate calculator System object hChan = comm.AWGNChannel('NoiseMethod', 'Signal to noise ratio (SNR)'); hErrorCalc = comm.ErrorRate; for n = 1:numSNR hChan.SNR = SNR(n); rxSig = step(hChan,fadedSig); % Add Gaussian noise DeModData = step(hDemod,rxSig); reset(hErrorCalc) % Compute error rate. berVec(:,n) = step(hErrorCalc,Bernoulli,DeModData); end BER = berVec(1,:); % Compute theoretical performance results, for comparison. BERtheory = berfading(SNR,'dpsk',2,1); figure % Plot BER results. semilogy(SNR,BERtheory,'b-',SNR,BER,'r*'); legend('Theoretical BER','Empirical BER'); xlabel('SNR (dB)'); ylabel('BER'); title('Binary DPSK over Rayleigh Fading Channel'); % Step 1. Generating Bernoulli Source ObjectActive(handles.Btn_Model_Bernoulli, handles.Line1_1, 'on'); global gBernoulli gBernoulli = Bernoulli_Binary_Generator(gFrameSize_F); ActionDelay(DelayChecked, dDelayTime); % Step 2. Convolutional Encoder ObjectActive(handles.Btn_Model_Encoder, handles.Line1, 'on'); trel = poly2trellis(MemoryNum_M , GeneratorPoly); PolySize = size(GeneratorPoly); global gConvolutionalCode; gConvolutionalCode = ConvolutionalEncoder(gFrameSize_F,gBernoulli,EncoderOutputBit_N,ShiftBit_k,MemoryNum_M,trel); ActionDelay(DelayChecked, dDelayTime); % 1 -> -1 and 0 -> 1 % Step 3. Block Interleaver ObjectActive(handles.Btn_Model_Interleaver, handles.Line2, 'on'); permVec = randperm(gFrameSize_F*gTimesOfOutputBits)'; global gInverleaverData; gInverleaverData = Interleaver('BlockInterleaver', gConvolutionalCode', permVec); ActionDelay(DelayChecked, dDelayTime); % Step 4. BPSK Modulator ObjectActive(handles.Btn_Model_Modulator, handles.Line3, 'on'); global gModData; gModData = BPSK_Modulator(gInverleaverData); ActionDelay(DelayChecked, dDelayTime); % Step 5. Wireless Channel: AWGN and Rayleigh global gNoiseCode; gNoiseCode = WirelessChannel_Rayleigh(RayleighSpectrumType,CarrierFrequency,MobileSpeed_Low,gModData); % not finished yet % Step 6. BPSK Demodulator ObjectActive(handles.Btn_Model_Demodulator, handles.Line5, 'on'); global DeModData; DeModData = BPSK_Demodulator(gNoiseCode); ActionDelay(DelayChecked, dDelayTime); % Step 7. Block Deinterleaver ObjectActive(handles.Btn_Model_Deinterleaver, handles.Line6, 'on'); global gDegInverleaverData; gDegInverleaverData = Deinterleaver('BlockInterleaver',DeModData,permVec); ActionDelay(DelayChecked, dDelayTime); % Step 8. Viterbi Decoder ObjectActive(handles.Btn_Model_Decoder, handles.Line7, 'on'); global gDecoded; gDecoded = ViterbiDecoder(gDegInverleaverData, VitebiDecisionType, 'cont', 2,trel); % Issue: soft doesn't work ActionDelay(DelayChecked, dDelayTime); % Step 9. Error Rate Calc ObjectActive(handles.Btn_Model_ErrorRateCalc, handles.Line8, 'on'); rate = ErrorRateCalc(gBernoulli,gDecoded) ActionDelay(DelayChecked, dDelayTime); global gresult_msg; fprintf('Error Rate: %d\n', rate); %-------------------------------------------------------------------------- % Step 1. Generating Bernoulli Source % Sequence: 0 and 1 function Bernoulli = Bernoulli_Binary_Generator(frame_size) %global Bernoulli; Bernoulli = randi([0 1],1,frame_size); %-------------------------------------------------------------------------- % Step 2. Convolutional Encoder function ConvolutionalCode = ConvolutionalEncoder(leng, source, Output_N, shift_k, Memory_Element_M, Trellis) hConvEnc = comm.ConvolutionalEncoder(Trellis); ConvolutionalCode = step(hConvEnc,source')'; % Encode the message. %-------------------------------------------------------------------------- % tblen is a positive integer scalar that specifies the traceback depth. % If the code rate is 1/2, a typical value for tblen is about 5 times the constraint length of the code. % http://www.mathworks.com/help/comm/ref/vitdec.html function Decoded = ViterbiDecoder(NoiseSource, DecissionType, Opmode, TracebackDepth, Trellis) if strcmp(DecissionType , 'hard') hVitDec = comm.ViterbiDecoder(Trellis, 'InputFormat', 'hard','TracebackDepth', TracebackDepth, 'TerminationMethod', 'Truncated'); Decoded = step(hVitDec, NoiseSource); % Decode. elseif strcmp(DecissionType , 'soft') % To prepare for soft-decision decoding, map to decision values. [x,qcode] = quantiz(1-2*NoiseSource,[-.75 -.5 -.25 0 .25 .5 .75],[7 6 5 4 3 2 1 0]); Decoded = vitdec(qcode,Trellis,TracebackDepth,Opmode,DecissionType, 3); % Decode. end %-------------------------------------------------------------------------- % Step 5. Wireless Channel: AWGN function NoiseCode = WirelessChannel_AWGN(leng,source, SNR) hAWGN = comm.AWGNChannel('NoiseMethod', 'Signal to noise ratio (SNR)','SNR',SNR); %hAWGN = comm.AWGNChannel('NoiseMethod', 'Signal to noise ratio (SNR)','SNR',SNR); NoiseCode = step(hAWGN, source); %-------------------------------------------------------------------------- % Step 5. Wireless Channel: Rayleigh function RayleighData = WirelessChannel_Rayleigh(DopplerType, Frequency, Speed, NoiseSignal) % ts is the sample time of the input signal, in seconds. fd is the maximum Doppler shift, in hertz. fm = DopplerShift((Speed*1000)/3600,Frequency*10^6); if strcmp(DopplerType,'flat') == 1 channel = rayleighchan(1/Frequency,fm); % Create object. channel.DopplerSpectrum = doppler.flat; elseif strcmp(DopplerType,'jakes') == 1 channel = rayleighchan(1/Frequency,fm); % Create object. end data=filter(channel,NoiseSignal); % http://www.mathworks.com/matlabcentral/answers/13373-ber-calculation-bpsk-simulation-with-rayleigh-channel hAWGN = comm.AWGNChannel('NoiseMethod', 'Signal to noise ratio (SNR)','SNR',10); %hAWGN = comm.AWGNChannel('NoiseMethod','Signal to noise ratio (SNR)','SNR',SNR); % NoiseCode = step(hAWGN, source); RayleighData = step(hAWGN,data); % Add Gaussian noise %RayleighData = step(hDemod, rxSig); % Demodulate %-------------------------------------------------------------------------- function intData = Interleaver(InterleaverType, SourceData, PermutationVector) if strcmp(InterleaverType,'BlockInterleaver') hInt = comm.BlockInterleaver(PermutationVector); intData = step(hInt, SourceData); end %-------------------------------------------------------------------------- function deIntData = Deinterleaver(InterleaverType, SourceData, PermutationVector) if strcmp(InterleaverType,'BlockInterleaver') hDeInt = comm.BlockDeinterleaver(PermutationVector); deIntData = step(hDeInt, SourceData); end %-------------------------------------------------------------------------- function gModData = BPSK_Modulator(Data) % Create a BPSK modulator System object hModulator = comm.BPSKModulator; %constellation(hModulator); % Modulate the data gModData = step(hModulator, Data); %-------------------------------------------------------------------------- function DeModData = BPSK_Demodulator(noisySignal) hDemod = comm.BPSKDemodulator; DeModData = step(hDemod,noisySignal); %-------------------------------------------------------------------------- function fm = DopplerShift(v,fc) fm = (v/(3*10^8))*fc; %Hz %-------------------------------------------------------------------------- function rate = ErrorRateCalc(SourceCode, DecodedCode) hErrorCalc = comm.ErrorRate; reset(hErrorCalc) [number,rate] = biterr(DecodedCode',SourceCode); %-------------------------------------------------------------------------- function DrawSquareWave(title_name,x_axis_label, y_axis_label, bit_array, min_x, max_x, min_y, max_y) figure t= 0:max_x; bit_array(max_x+1) = bit_array(max_x); % draw the last bit stairs(t, bit_array,'LineWidth',2); axis([min_x max_x min_y max_y]) %grid on xlabel(x_axis_label); ylabel(y_axis_label); title(title_name); %--------------------------------------------------------------------------