elsebegini=0;cp0=~cp0;end
end
endmodule
随机码序列产生器(m序列):
modulePN_Seq(clk,reset_n,dataout);
inputclk;
inputreset_n;
outputdataout;
reg[7:
1]c;
always@(posedgeclkornegedgereset_n)
begin
if(!
reset_n)
c<=7'b1001110;
else
begin
c[7]<=c[6];
c[6]<=c[5];
c[5]<=c[4];
c[4]<=c[3];
c[3]<=c[2];
c[2]<=c[1];
c[1]<=c[2]^c[3]^c[4]^c[7];
end
end
assigndataout=c[7];
endmodule
差分编码器:
moduledif(clk,reset_n,in,out);
inputclk;
inputreset_n;
inputin;
outputout;
reg[1:
0]o;
always@(posedgeclkornegedgereset_n)
begin
if(!
reset_n)
o<=1;
else
begin
o<=in^o;
end
end
assignout=o;
endmodule
控制器:
moduleController(clk,reset_n,s,address,cp);
inputclk;
inputreset_n;
inputcp;
inputs;//相对码
output[4:
0]address;
reg[4:
0]address_data;
reg[4:
0]count;
regsign;
always@(posedgecp)
begin
if(s==0)
count<=5'b10000;
elseif(s==1)count<=5'b00000;
sign<=1;
end
always@(posedgeclkornegedgereset_n)
begin
if(!
reset_n)
address_data<=5'b00000;
elsebegin
if(sign==1)
begin
address_data<=count;
sign<=0;
end
address_data<=address_data+1'b1;
if(address_data==32)
address_data<=5'b00000;
end
end
assignaddress=address_data;
endmodule
正弦波形查找表:
moduleLookUpTable(clk,reset_n,address,dataout);//正弦载波采样表
inputclk;
inputreset_n;
input[4:
0]address;
output[7:
0]dataout;
reg[7:
0]LUT[0:
31];
always@(posedgeclkornegedgereset_n)
begin
if(!
reset_n)
begin
LUT[0]<=128;//用C编程计算出的查找表采样值填在这里
LUT[1]<=152;
LUT[2]<=176;
LUT[3]<=198;
LUT[4]<=218;
LUT[5]<=234;
LUT[6]<=245;
LUT[7]<=253;
LUT[8]<=255;
LUT[9]<=253;
LUT[10]<=245;
LUT[11]<=234;
LUT[12]<=218;
LUT[13]<=198;
LUT[14]<=176;
LUT[15]<=152;
LUT[16]<=128;
LUT[17]<=103;
LUT[18]<=79;
LUT[19]<=57;
LUT[20]<=37;
LUT[21]<=22;
LUT[22]<=10;
LUT[23]<=2;
LUT[24]<=0;
LUT[25]<=2;
LUT[26]<=10;
LUT[27]<=22;
LUT[28]<=37;
LUT[29]<=57;
LUT[30]<=79;
LUT[31]<=103;
end
end
assigndataout=LUT[address];
endmodule
3、功能仿真和时序仿真结果的波形
功能仿真:
时序仿真:
实验二MATLAB实验OFDM误码率仿真(AWGN)
一、实验目的:
1、掌握OFDM的基本原理。
2、掌握用Matlab搭建OFDM系统的基本方法
3、用MATLAB进行OFDM系统在AWGN信道下误码率分析。
二、实验报告要求
1.所有程序完整的源代码(.m文件)以及注释。
2.仿真结果。
对于所有的图形结果(包括波形与仿真曲线等),将图形保存成.tif或者.emf的格式并插入word文档。
三、实验结果
1、所有程序完整的源代码(.m文件)以及注释:
%16QAM的调制函数
function[complex_qam_data]=qam16(bitdata)
%modulationof16QAM,modulatebitdatato16QAMcomplexsignal
X1=reshape(bitdata,4,length(bitdata)/4)';
d=1;%mindistanceofsymble
fori=1:
length(bitdata)/4;
forj=1:
4
X1(i,j)=X1(i,j)*(2^(4-j));
end
source(i,1)=1+sum(X1(i,:
));%converttothenumber1to16
end
mapping=[-3*d3*d;
-d3*d;
d3*d;
3*d3*d;
-3*dd;
-dd;
dd;
3*dd;
-3*d-d;
-d-d;
d-d;
3*d-d;
-3*d-3*d;
-d-3*d;
d-3*d;
3*d-3*d];
fori=1:
length(bitdata)/4
qam_data(i,:
)=mapping(source(i),:
);%datamapping
end
complex_qam_data=complex(qam_data(:
1),qam_data(:
2));
%16QAM的解调函数。
function[demodu_bit_symble]=demoduqam16(Rx_serial_complex_symbols)
%将得到的串行16QAM数据解调成二进制比特流
complex_symbols=reshape(Rx_serial_complex_symbols,length(Rx_serial_complex_symbols),1);
d=1;
mapping=[-3*d3*d;
-d3*d;
d3*d;
3*d3*d;
-3*dd;
-dd;
dd;
3*dd;
-3*d-d;
-d-d;
d-d;
3*d-d;
-3*d-3*d;
-d-3*d;
d-3*d;
3*d-3*d];
complex_mapping=complex(mapping(:
1),mapping(:
2));
fori=1:
length(Rx_serial_complex_symbols);
forj=1:
16;
metrics(j)=abs(complex_symbols(i,1)-complex_mapping(j,1));
end
[min_metricdecode_symble(i)]=min(metrics);%将离某星座点最近的值赋给decode_symble(i)
end
decode_bit_symble=de2bi((decode_symble-1)','left-msb');
demodu_bit_symble=reshape(decode_bit_symble',1,length(Rx_serial_complex_symbols)*4);
%加窗函数
function[rcosw]=rcoswindow(beta,Ts)
%定义升余弦窗,其中beta为滚降系数,Ts为包含循环前缀的OFDM符号的长度,Ts为正偶数
t=0:
(1+beta)*Ts;
rcosw=zeros(1,(1+beta)*Ts);
fori=1:
beta*Ts;
rcosw(i)=0.5+0.5*cos(pi+t(i)*pi/(beta*Ts));
end
rcosw(beta*Ts+1:
Ts)=1;
forj=Ts+1:
(1+beta)*Ts+1;
rcosw(j-1)=0.5+0.5*cos((t(j)-Ts)*pi/(beta*Ts));
end
rcosw=rcosw';%变换为列向量
%OFDM主程序
clearall;
closeall;
carrier_count=200;%子载波数
symbols_per_carrier=12;%每子载波含符号数
bits_per_symbol=4;%每符号含比特数,16QAM调制
IFFT_bin_length=512;%FFT点数
PrefixRatio=1/4;%保护间隔与OFDM数据的比例1/6~1/4
GI=PrefixRatio*IFFT_bin_length;%每一个OFDM符号添加的循环前缀长度为1/4*IFFT_bin_length即保护间隔长度为128
beta=1/32;%窗函数滚降系数
GIP=beta*(IFFT_bin_length+GI);%循环后缀的长度20
SNR=15;%信噪比dB
%==================================================
%================信号产生===================================
baseband_out_length=carrier_count*symbols_per_carrier*bits_per_symbol;%所输入的比特数目
carriers=(1:
carrier_count)+(floor(IFFT_bin_length/4)-floor(carrier_count/2));%共轭对称子载波映射复数数据对应的IFFT点坐标
conjugate_carriers=IFFT_bin_length-carriers+2;%共轭对称子载波映射共轭复数对应的IFFT点坐标
baseband_out=round(rand(1,baseband_out_length));%输出待调制的二进制比特流
%==============16QAM调制====================================
complex_carrier_matrix=qam16(baseband_out);%列向量
complex_carrier_matrix=reshape(complex_carrier_matrix',carrier_count,symbols_per_carrier)';%symbols_per_carrier*carrier_count矩阵
figure
(1);
plot(complex_carrier_matrix,'*r');%16QAM调制后星座图
title('16QAM调制后星座图')
axis([-4,4,-4,4]);
gridon
%=================IFFT===========================
IFFT_modulation=zeros(symbols_per_carrier,IFFT_bin_length);%添0组成IFFT_bin_lengthIFFT运算
IFFT_modulation(:
carriers)=complex_carrier_matrix;%未添加导频信号,子载波映射在此处
IFFT_modulation(:
conjugate_carriers)=conj(complex_carrier_matrix);%共轭复数映射
%=================================================================
signal_after_IFFT=ifft(IFFT_modulation,IFFT_bin_length,2);%OFDM调制即IFFT变换
time_wave_matrix=signal_after_IFFT;%时域波形矩阵,行为每载波所含符号数,列ITTF点数,N个子载波映射在其内,每一行即为一个OFDM符号
%=====================添加循环前缀与后缀============
XX=zeros(symbols_per_carrier,IFFT_bin_length+GI+GIP);
fork=1:
symbols_per_carrier;
fori=1:
IFFT_bin_length;
XX(k,i+GI)=signal_after_IFFT(k,i);
end
fori=1:
GI;
XX(k,i)=signal_after_IFFT(k,i+IFFT_bin_length-GI);%添加循环前缀
end
forj=1:
GIP;
XX(k,IFFT_bin_length+GI+j)=signal_after_IFFT(k,j);%添加循环后缀
end
end
time_wave_matrix_cp=XX;%添加了循环前缀与后缀的时域信号矩阵,此时一个OFDM符号长度为IFFT_bin_length+GI+GIP=660
%==============OFDM符号加窗================================
windowed_time_wave_matrix_cp=zeros(1,IFFT_bin_length+GI+GIP);
fori=1:
symbols_per_carrier
windowed_time_wave_matrix_cp(i,:
)=real(time_wave_matrix_cp(i,:
)).*rcoswindow(beta,IFFT_bin_length+GI)';%加窗升余弦窗
end
%========================生成发送信号,并串变换=====================
windowed_Tx_data=zeros(1,symbols_per_carrier*(IFFT_bin_length+GI)+GIP);
windowed_Tx_data(1:
IFFT_bin_length+GI+GIP)=windowed_time_wave_matrix_cp(1,:
);
fori=1:
symbols_per_carrier-1;
windowed_Tx_data((IFFT_bin_length+GI)*i+1:
(IFFT_bin_length+GI)*(i+1)+GIP)=windowed_time_wave_matrix_cp(i+1,:
);%并串转换,循环后缀与循环前缀相叠加
end
%=======================================================
Tx_data=reshape(windowed_time_wave_matrix_cp',(symbols_per_carrier)*(IFFT_bin_length+GI+GIP),1)';%加窗后循环前缀与后缀不叠加的串行信号
%=================================================================
temp_time1=(symbols_per_carrier)*(IFFT_bin_length+GI+GIP);%加窗后循环前缀与后缀不叠加发送总位数
figure
(2)
subplot(2,1,1);
plot(0:
temp_time1-1,Tx_data);%循环前缀与后缀不叠加发送的信号波形
gridon
ylabel('Amplitude(volts)')
xlabel('Time(samples)')
title('循环前后缀不叠加的OFDMTimeSignal')
temp_time2=symbols_per_carrier*(IFFT_bin_length+GI)+GIP;
subplot(2,1,2);
plot(0:
temp_time2-1,windowed_Tx_data);%循环后缀与循环前缀相叠加发送信号波形
gridon
ylabel('Amplitude(volts)')
xlabel('Time(samples)')
title('循环前后缀叠加的OFDMTimeSignal')
%===============加窗的发送信号频谱=================================
symbols_per_average=ceil(symbols_per_carrier/5);%符号数的1/5,10行
avg_temp_time=(IFFT_bin_length+GI+GIP)*symbols_per_average;%点数,10行数据,10个符号
averages=floor(temp_time1/avg_temp_time);
average_fft(1:
avg_temp_time)=0;%分成5段
fora=0:
(averages-1)
subset_ofdm=Tx_data(((a*avg_temp_time)+1):
((a+1)*avg_temp_time));%利用循环前缀后缀未叠加的串行加窗信号计算频谱
subset_ofdm_f=abs(fft(subset_ofdm));%分段求频谱
average_fft=average_fft+(subset_ofdm_f/averages);%总共的数据分为5段,分段进行FFT,平均相加
end
average_fft_log=20*log10(average_fft);
figure(3)
subplot(2,1,2)
plot((0:
(avg_temp_time-1))/avg_temp_time,average_fft_log)%归一化0/avg_temp_time:
(avg_temp_time-1)/avg_temp_time
holdon
plot(0:
1/IFFT_bin_length:
1,-35,'rd')
gridon
axis([00.5-40max(average_fft_log)])
ylabel('Magnitude(dB)')
xlabel('NormalizedFrequency(0.5=fs/2)')
title('加窗的发送信号频谱')
%====================添加噪声=================================
Tx_signal_power=var(windowed_Tx_data);%发送信号功率
linear_SNR=10^(SNR/10);%线性信噪比
noise_sigma=Tx_signal_power/linear_SNR;
noise_scale_factor=sqrt(noise_sigma);%标准差sigma
noise=randn(1,((symbols_per_carrier)*(IFFT_bin_length+GI))+GIP)*noise_scale_factor;%产生正态分布噪声序列
Rx_data=windowed_Tx_data+noise;%接收到的信号加噪声
%=============接收信号串/并变换去除前缀与后缀==================
Rx_data_matrix=zeros(symbols_per_carrier,IFFT_bin_length+GI+GIP);
fori=1:
symbols_per_carrier;
Rx_data_matrix(i,:
)=Rx_data(1,(i-