提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
前言
本文讲述了使用Vivado 仿真FPGA实现pi/4 QPSK 调制解调的过程,并将调制过程中的信号导出至matlab进行分析。
一、 π / 4 \pi/4 π/4 QPSK 调制解调原理
1 π / 4 \pi/4 π/4 QPSK 信号介绍
相移键控(PSK)的解调原理为通过数字码字控制载波信号(正弦信号)相位。其相对于ASK具有能量稳定的优先,相对于FSK,具有频带窄的优势。
QPSK指的是共有4种相位,通过数字码元{00,01,10,11},进行控制,通常其相位为{ 0 , π / 2 , π , 3 π / 2 0,\pi/2,\pi,3\pi/2 0,π/2,π,3π/2}。
为了解决载波同步的问题,引入了差分编码技术DQPSK,差分编码指的是码字不是直接控制载波信号相位,而是控制当前码元和上一码元的相位差。
为了解决相邻码字相位差可能出现
π
\pi
π跳变的情况(这在实际的通信系统中会引入高频分量),引入了
π
/
4
\pi/4
π/4 QPSK调制。其信号有8个相位,分为两组,每次信号会从其中一组跳到另外一组,导致最大相位差为
3
π
/
4
3\pi/4
3π/4。
如图所示,上下左右为一组,左上右上左下右下为一组,码字控制的相位跳变为
00
(
π
/
4
)
01
(
3
π
/
4
)
10
(
−
π
/
4
)
11
(
−
3
π
/
4
)
00 ( \pi/4) \quad 01 (3\pi/4) \quad 10 (-\pi/4)\quad 11 (-3\pi/4)
00(π/4)01(3π/4)10(−π/4)11(−3π/4)
2 π / 4 \pi/4 π/4 QPSK 调制原理
如图所示,主流的调制方法是方法二,因为控制幅度比控制相位差来的简单,本文中由于DDSip核可以直接控制相位输入,因此使用方法1 进行调制。
3 π / 4 \pi/4 π/4 QPSK 解调原理
二、Vivado 和 Matlab实现
主体流程图如下
1 发送码字生成
matlab 码字写入文件
a1 = 0.4;
a2 = 0.7;
a3 = 0.9;
len = 1e4; % 码字长度以及各个码字出现的概率
close all
fid=fopen('A2.txt','wb');%写入文件路径
for ii = 1:len
c = rand(1);% 按不同概率生成码字
if(c>a3)
fprintf(fid,'%d\n',1);
fprintf(fid,'%d\n',1); %11
elseif(c>a2)
fprintf(fid,'%d\n',1);
fprintf(fid,'%d\n',0); % 10
elseif(c>a1)
fprintf(fid,'%d\n',0);
fprintf(fid,'%d\n',1); %01
else
fprintf(fid,'%d\n',0);
fprintf(fid,'%d\n',0); %00
end
end
fclose(fid)
;
teshbench 读取码字
integer file ;
file = $fopen("E:\\qpsk_src\\qpsk1\\A2.txt","r"); // 读取文件
always //读取码字
begin
# 1600;
if(bit_in_clk)
bit_in_clk = !bit_in_clk;//生成时钟,
else begin
bit_in_clk = !bit_in_clk;
if(bit_idx<bit_len)
begin
$fscanf(file,"%b",bit_in); //读取码字输入比特流
bit_idx=bit_idx+1;
end
else
begin
$fclose(file);
end
end
end
2. π / 4 \pi/4 π/4 QPSK 调制
串并变换
always @(posedge bit_clk) begin
bit_buffer_inter <= {bit_buffer_inter[0], bit_in}; // 移位寄存器
idx = !idx;
if (idx) begin
bit_ready <= 1'b1; //存储2位后完成后 发出可以调制相位的信号
bit_buffer_out<=bit_buffer_inter;
end
end //串并变换 将输入比特流存储至两位qpsk码元的缓存区
本地载波信号
dds_compiler_0 dds0 (
.aclk(clk),
.s_axis_phase_tvalid(high),
.s_axis_phase_tdata(phase_in_reg), //输入相位!!!!!!!!!!!!!
//也是本程序控制的相位
.m_axis_data_tvalid(a2),
.m_axis_data_tdata(dds_out) // 本地载波
);
码字控制相位
always @(posedge clk) begin //根据二位码元进行相位累加 改变ddsip核生成正弦波的相位
if (bit_ready) begin
case (bit_buffer_out)
2'b00: phase_in_reg = phase_in_reg+PHASE_SHIFT_PI_4; // 相位45度 对应00
2'b01: phase_in_reg = phase_in_reg+PHASE_SHIFT_fuPI_4; // 相位-45度 对应01
2'b10: phase_in_reg = phase_in_reg+PHASE_SHIFT_3PI_4; // 相位135度 对应10
2'b11: phase_in_reg = phase_in_reg+PHASE_SHIFT_fu3PI_4;// 相位-135度 对应11
default: phase_in_reg = phase_in_reg+PHASE_SHIFT_PI_4; // 默认输出0
endcase
phase_pre = phase_in_reg;
bit_ready = 1'b0; //调制完相位后准备接收下一码字
end
end
加噪
matlab生成噪声rom核系数
close all;
clear all;
clc;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
fc=3e6;
fs=65e6;
L=1024;
ADC_bit=10;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
t=0:1/fs:(L-1)/fs;
noise=randn(1,length(t));
st=noise;
y=st/4;%max(abs(st));
yt=round(y*(2^(ADC_bit-1)-1));
figure(1);
plot(st);hold on;
figure(2);
plot(y);hold on;
figure(3);
plot(yt);hold on;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% MATLAB
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
fid=fopen('WN.coe','w');
fprintf(fid,'Memory_Initialization_Radix = 2;\r\n');
fprintf(fid,'Memory_Initialization_Vector = \r\n');
for p=1:L
B_s=dec2bin(yt(p)+(yt(p)<0)*2^ADC_bit,ADC_bit);
for q=1:ADC_bit
if B_s(q)=='1'
data=1;
else
data=0;
end
fprintf(fid,'%d',data);
end
if (p<L)
fprintf(fid,',\r\n');
else
fprintf(fid,';\r\n');
end
end
fclose(fid);
fpga通过rom核加噪
blk_mem_gen_0 noise_rom (
.clka(clk), // input wire clka
.addra(addra), // input wire [9 : 0] addra
.douta(noise) // output wire [7 : 0] douta
); //噪声生成rom核,噪声
mult_gen_1 noise_mul (
.CLK(clk), // input wire CLK
.A(noise), // input wire [9 : 0] A
.B(noise_factor), // input wire [7 : 0] B //信噪比输入
.P(noise1) // output wire [16 : 0] P
); //噪声乘法ip核 进行噪声缩小,
c_addsub_2 noise_add (
.A(noise2), // input wire [9 : 0] A
.B(dds_out), // input wire [7 : 0] B
.CLK(clk), // input wire CLK
.CE(high), // input wire CE
.S(noised_sig1) // 信号与噪声相加
调制模块接口定义
module qpsk_mod(
input clk, // 时钟信号
input rst_n, // 异步复位信号,低电平有效
input bit_in, // 串行输入比特
input bit_clk, // 输入比特时钟
input wire [7:0] noise_factor, // SNR 控制 44 0dB 14 10dB
output wire [7:0] sin_out, // QPSK信号
output wire [1:0] qpsk_code_out // QPSK码字
);
3. π / 4 \pi/4 π/4 QPSK 解调
本地载波信号
dds_compiler_0 dds1 ( //cos
.aclk(clk), // input wire aclk
.s_axis_phase_tvalid(high), // input wire s_axis_phase_tvalid
.s_axis_phase_tdata(phase_in_reg), // input wire [15 : 0] s_axis_phase_tdata
.m_axis_data_tvalid(a2), // output wire m_axis_data_tvalid
.m_axis_data_tdata(cos_out) // output wire [7 : 0] m_axis_data_tdata
);
dds_compiler_0 dds2 ( //sin
.aclk(clk), // input wire aclk
.s_axis_phase_tvalid(high), // input wire s_axis_phase_tvalid
.s_axis_phase_tdata(PHASE_SHIFT_fu90), // input wire [15 : 0] s_axis_phase_tdata
.m_axis_data_tvalid(a1), // output wire m_axis_data_tvalid
.m_axis_data_tdata(sin_out) // output wire [7 : 0] m_axis_data_tdata
);
相乘,低通
//首先将输入信号分别和两路本地载波信号相乘
mult_gen_0 mul1 (
.CLK(clk), // input wire CLK
.A(cos_out), // input wire [7 : 0] A
.B(sin_in), // input wire [7 : 0] B
.P(cos_mul) // output wire [15 : 0] P
);
mult_gen_0 mul2 (
.CLK(clk), // input wire CLK
.A(sin_out), // input wire [7 : 0] A
.B(sin_in), // input wire [7 : 0] B
.P(sin_mul) // output wire [15 : 0] P
);
//随后分别对两路相乘后信号进行滤波 滤除高频分量,剩余相位信息
fir_compiler_0 cos_lpf (
.aclk(clk), // input wire aclk
.s_axis_data_tvalid(high), // input wire s_axis_data_tvalid
.s_axis_data_tready(s_axis_data_tready), // output wire s_axis_data_tready
.s_axis_data_tdata({cos_mul}), // input wire [15 : 0] s_axis_data_tdata
.m_axis_data_tvalid(m_axis_data_tvalid), // output wire m_axis_data_tvalid
.m_axis_data_tdata(lpf_out1) // output wire [39 : 0] m_axis_data_tdata
);
fir_compiler_0 sin_lpf (
.aclk(clk), // input wire aclk
.s_axis_data_tvalid(high), // input wire s_axis_data_tvalid
.s_axis_data_tready(s_axis_data_tready), // output wire s_axis_data_tready
.s_axis_data_tdata(sin_mul), // input wire [15 : 0] s_axis_data_tdata
.m_axis_data_tvalid(m_axis_data_tvalid), // output wire m_axis_data_tvalid
.m_axis_data_tdata(lpf_out2) // output wire [39 : 0] m_axis_data_tdata
);
利用和差化积计算相位差
//以下四个乘法和两个加减法是根据和差化积公式算出当前码元和上一码元的相位差,这代表着两位qpsk码字信息
mult_gen_0 coscos (
.CLK(clk), // input wire CLK
.A(cos_mul_lpf), // input wire [7 : 0] A
.B(cos_mul_lpf_old), // input wire [7 : 0] B
.P(cc1) // output wire [15 : 0] P
);
mult_gen_0 sinsin (
.CLK(clk), // input wire CLK
.A(q), // input wire [7 : 0] A
.B(sin_mul_lpf_old), // input wire [7 : 0] B
.P(ss1) // output wire [15 : 0] P
);
mult_gen_0 cossin (
.CLK(clk), // input wire CLK
.A(cos_mul_lpf), // input wire [7 : 0] A
.B(sin_mul_lpf_old), // input wire [7 : 0] B
.P(cs1) // output wire [15 : 0] P
);
mult_gen_0 sincos (
.CLK(clk), // input wire CLK
.A(q), // input wire [7 : 0] A
.B(cos_mul_lpf_old), // input wire [7 : 0] B
.P(sc1) // output wire [15 : 0] P
);
c_addsub_0 csub (
.A(cc), // input wire [7 : 0] A
.B(ss), // input wire [7 : 0] B
.CLK(clk), // input wire CLK
.CE(high), // input wire CE
.S(cossub1) // output wire [8 : 0] S
);
c_addsub_1 ssub (
.A(sc), // input wire [7 : 0] A
.B(cs), // input wire [7 : 0] B
.CLK(clk), // input wire CLK
.CE(high), // input wire CE
.S(sinsub1) // output wire [7 : 0] S
);
与QPSK码字判决
always @(posedge clk or negedge rst_n) begin
if (!rst_n)
begin
bit_buffer_out <= 2'b00;
bit_buffer_inter <= 2'b00;
bit_ready <= 1'b0;
end
else
begin
q<=-sin_mul_lpf; //sin项的正负变换
end
if(code_clk_idx>=clk_rto)
begin
code_clk_idx<=8'd0;
inter_clk1<=!inter_clk1;
end
else
begin
code_clk_idx<=code_clk_idx+1;
end
if((pre_idx>0)||(bit_ready==1))
begin
if(pre_idx>=pretect_len)
begin
latency_idx<=0;
pre_idx<=0;
end
else
begin
pre_idx=pre_idx+1;
latency_idx=latency_idx+1;
end
end
if(latency_idx==latency) //根据cos和sin的值进行判决
begin
if(cossub[7]==0)
if(sinsub[7]==0)
bit_buffer_inter=2'b00;
else
bit_buffer_inter=2'b01;
else
if(sinsub[7]==0)
bit_buffer_inter=2'b10;
else
bit_buffer_inter=2'b11;
end
// bit_clk_old<=bit_clk;
end
并串变换
//两位码字解调结束后,串行输出比特流
always @(posedge inter_clk1) begin
cos_mul_lpf_old <= cos_mul_lpf;
sin_mul_lpf_old <= q;
if(bit_ready)
begin
if(idx==0)
bit_ready<=0;
begin
end
idx<= idx-1;
out_reg <= bit_buffer_out[idx];
end
end
本文系统中解调模块无须比特始终,只需qpsk信号进行输入,其中配备了位同步模块
//位同步模块,通过捕捉相位差信息在码字来临时的变化,提取码元同步信息
bit_sync my_sync(
.clk(clk),
.cos(cossub),
.sin(sinsub),
.bit_sync_pluse(qpsk_sync)
);
//位同步信息来临时,开始解调
always @(posedge qpsk_sync) begin
if(pre_idx==0)
begin
latency_idx<=0;
bit_ready=1;
code_clk_idx<=0;
inter_clk1<=0;
bit_buffer_out <= bit_buffer_inter;
end
// end
end
位同步模块
`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2024/09/09 20:59:18
// Design Name:
// Module Name: bit_sync
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
module bit_sync(
input wire clk,
input wire [7:0] cos,
input wire [7:0] sin,
output bit_sync_pluse
);
// 提取位同步的思想是当输入余弦项或正弦项持续五个时钟朝同一方向变化时,认为码元发生了变化,输出位同步信号
wire[7:0] cosand;
wire[7:0] sinand;
wire[7:0] cosor;
wire[7:0] sinor;
wire cos_same;
wire sin_same;
reg [7:0] cosold_1;
reg [7:0] cosold_2;
reg [7:0] cosold_3;
reg [7:0] cosold_4;
reg [7:0] cosold_5;
reg [7:0] cossub1;
reg [7:0] cossub2;
reg [7:0] cossub3;
reg [7:0] cossub4;
reg [7:0] cossub5;
reg [7:0] sinsub1;
reg [7:0] sinsub2;
reg [7:0] sinsub3;
reg [7:0] sinsub4;
reg [7:0] sinsub5;
reg [7:0] sinold_1;
reg [7:0] sinold_2;
reg [7:0] sinold_3;
reg [7:0] sinold_4;
reg [7:0] sinold_5;
wire cos_eq_0 ;
wire sin_eq_0;
assign cos_eq_0=cossub1||cossub2||cossub3||cossub4||cossub5;
assign sin_eq_0=sinsub1||sinsub2||sinsub3||sinsub4||sinsub5;
assign cosand = cossub1&cossub2&cossub3&cossub4&cossub5;
assign sinand = sinsub1&sinsub2&sinsub3&sinsub4&sinsub5;
assign cosor = cossub1|cossub2|cossub3|cossub4|cossub5;
assign sinor = sinsub1|sinsub2|sinsub3|sinsub4|sinsub5;
assign cos_same = cosand[7]|(!cosor[7]);
assign sin_same = sinand[7]|(!sinor[7]);
assign bit_sync_pluse = (cos_same|sin_same)&cos_eq_0&sin_eq_0;
//对输入的正弦项或余弦项进行差分,
always @(posedge clk) begin
cosold_1<=cos;
cosold_2<=cosold_1;
cosold_3<=cosold_2;
cosold_4<=cosold_3;
cosold_5<=cosold_4;
sinold_1<=sin;
sinold_2<=sinold_1;
sinold_3<=sinold_2 ;
sinold_4<=sinold_3 ;
sinold_5<=sinold_4 ;
cossub1<=cos-cosold_1;
cossub2<=cosold_1-cosold_2;
cossub3<=cosold_2-cosold_3;
cossub4<=cosold_3-cosold_4;
cossub5<=cosold_4-cosold_5;
sinsub1<=sin-sinold_1;
sinsub2<=sinold_1-sinold_2;
sinsub3<=sinold_2-sinold_3;
sinsub4<=sinold_3-sinold_4;
sinsub5<=sinold_4-sinold_5;
end
endmodule
解调模块接口
module qpsk_demod(
input clk, // 时钟信号
input rst_n, // 异步复位信号,低电平有效
// input bit_in, // 串行输入比特
// input bit_clk, // 输入比特时钟 //取消输入 加入位同步
input wire [7:0] sin_in, // 输入的加噪后的qpsk信号
output wire out , // 输出比特流
output wire inter_clk_out // 输出比特流时钟
)
4 仿真信号写入
file2 = $fopen("E:\\qpsk_src\\qpsk1\\B2.txt","w");//输出比特流
f_qpsk_in = $fopen("E:\\qpsk_src\\qpsk1\\qpsk_in.txt","w");// qpsk调制码字
f_qpsk_out = $fopen("E:\\qpsk_src\\qpsk1\\qpsk_out.txt","w");// qpsk解调码字
f_sin = $fopen("E:\\qpsk_src\\qpsk1\\sin.txt","w");// 纯qpsk信号
f_noise = $fopen("E:\\qpsk_src\\qpsk1\\noise.txt","w"); //噪声
f_nsin = $fopen("E:\\qpsk_src\\qpsk1\\nsin.txt","w");// 加噪信号
always @(negedge bit_out_clk) begin
$fwrite(file2,"%b\n",bit_out);
$fwrite(f_qpsk_in,"%b\n",qpsk_code_out);//将o_Ifir_R的值以整数形式写入It.txt文件,并换行
$fwrite(f_qpsk_out,"%b\n",qpsk_demod_out);
$fwrite(f_sin,"%b\n",qpsk_signal);//将o_Ifir_R的值以整数形式写入It.txt文件,并换行
$fwrite(f_noise,"%b\n",G_noise);//将o_Ifir_R的值以整数形式写入It.txt文件,并换行
$fwrite(f_nsin,"%b\n",noised_signal);//将o_Ifir_R的值以整数形式写入It.txt文件,并换行
end
5 主模块及调用
主模块接口
module main(
input clk, // 主时钟信号
input rst_n, // 异步复位信号,低电平有效
input bit_in, // 串行输入比特
input bit_in_clk, // 输入比特时钟
input wire [7:0] noise_factor, //噪声因子 取8'd44代表0dB 14代表0dB
output wire bit_out, // 输出比特流
output wire [1:0] qpsk_demod_out, //串并变化后调制前的两位qpsk码元
output wire [1:0]qpsk_code_out, //解调后的两位qpsk码元
output wire bit_out_clk , // 输出比特流时钟
output wire [7:0] sin_out, //加噪信号
output wire [7:0] dds_sin,//纯qpsk信号
output wire [9:0] Gnoise//纯噪声
);
testbench 调用主模块
main main_module(
.clk(clk), // 时钟信号
.rst_n(rst_n), // 异步复位信号,低电平有效
.bit_in(bit_in), // 串行输入比特
.bit_in_clk (bit_in_clk), // 输入比特时钟
.noise_factor(noise_factor), //噪声因子控制信噪比取8'd44代表0dB 14代表0dB
.bit_out(bit_out), // 输出比特流
.qpsk_demod_out(qpsk_demod_out), // 输出qpsk码字
// .inter_clk_out(inter_clk_out), //输出qpsk码字时钟
.qpsk_code_out(qpsk_code_out), //输入qpsk码字
.bit_out_clk(bit_out_clk), //输出比特时钟
.sin_out(noised_signal), //加噪信号
.dds_sin(qpsk_signal), //纯qpsk信号
.Gnoise(G_noise) //噪声
);
6 matlab 分析仿真过程
clear
close all
% ??????
clear; clc;
% ??????
clear; clc;
% ?????
EbN0_dB = 0:1:10; % ???????0dB?10dB
% QPSK?BER??
berQPSK = 0.5 * erfc(sqrt(10.^(EbN0_dB/10)));
% 8PSK?BER??????????????????
EsN0_dB = EbN0_dB + 10*log10(log2(8)); % ???Es/N0
% sinPi8 = sin(pi/8)^2;
% ber8PSK = 2/3 * qfunc(sqrt(2 * 10.^(EsN0_dB/10) * sinPi8));
% ??QPSK?8PSK?BER??
figure;
semilogy(EbN0_dB, berQPSK, 'b-o');
% hold on;
% semilogy(EbN0_dB, ber8PSK, 'r-x');
grid on;
xlabel('Eb/N0 (dB)');
ylabel('Bit Error Rate (BER)');
title('BER vs. Eb/N0 for QPSK');
legend('QPSK BER');
fprintf('err rate in theory in 0dB:%f\n', berQPSK(1));
fprintf('err rate in theory in 10dB:%f\n', berQPSK(end));
bit_in = textread('A2.txt','%s');
bit_out = textread('B2.txt','%s');
code_in = textread('qpsk_in.txt','%s');%????
code_out = textread('qpsk_out.txt','%s');%????
psk8_sin = textread('sin.txt','%s');%????
Gnoise = textread('noise.txt','%s');%????
noised_sin = textread('nsin.txt','%s');%????
len = length(code_in);
cd_in = zeros(1,len);
cd_out = zeros(1,len);
sin_d = zeros(1,len);;
n_d = zeros(1,len);;
nsin_d = zeros(1,len);;
blen = length(bit_out);
bi = zeros(1,blen);
bo = zeros(1,blen);
for ii = 1:len
cd_in(ii)=b2d(code_in{ii});
cd_out(ii)=b2d(code_out{ii});
sin_d(ii)=b2d(psk8_sin{ii});
n_d(ii)=b2d(Gnoise{ii});
nsin_d(ii)=b2d(noised_sin{ii});
end
for ii = 1:blen
bi(ii)=b2d(bit_in{ii});
bo(ii)=b2d(bit_out{ii});
end
xcorr_len = 300;
a1 = cd_in(1:xcorr_len);
a2 = cd_out(1:xcorr_len);
figure(2)
stairs(a1);
hold on
stairs(a2-5)
axis([0 xcorr_len -10 10])
title('qpsk code input/output');
legend('input code', 'output code')
a3 = xcorr(a1,a2);
figure(3)
title('input and output corelation')
plot(a3)
[~,delay] = max(a3);
delay = xcorr_len-delay;
% delay=6;
bit_len = len-delay;
right = zeros(1,bit_len);
right2=0;
bit_right_sum = 0;
for ii = 4:bit_len
right(ii) = cd_out(ii+delay)-cd_in(ii);
if(right(ii)~=0)
right2=right2+1;
end
end
a1 = bi(1:xcorr_len);
a2 = bo(1:xcorr_len);
figure(2)
stairs(a1);
hold on
stairs(a2-5)
axis([0 xcorr_len -10 10])
title('qpsk code input/output');
legend('input code', 'output code')
a3 = xcorr(a1,a2);
figure(3)
title('input and output corelation')
plot(a3)
[~,delayb] = max(a3);
delayb = xcorr_len-delayb;
% delay=6;
bit_len = len-delayb;
right = zeros(1,bit_len);
for ii = 4:bit_len
bit_right = bo(ii+delayb)-bi(ii);
if(bit_right~=0)
bit_right_sum=bit_right_sum+1;
end
end
right3 = bit_len-right2;
err = 1-right3/bit_len;
fprintf('symbol error rate:%f\n', err);
right6 = bit_len-bit_right_sum;
berr = 1-right6/bit_len;
fprintf('bit error rate:%f\n', berr);
figure(4)
plot(sin_d)
title('pure qpsk signal')
figure(5)
plot(n_d)
title('pure guassian noise')
figure(6)
plot(nsin_d)
title('noised signal')
sig_pwr = sum(nsin_d.^2);
n_pwr = sum(n_d.^2);
snr = sig_pwr/n_pwr;
fprintf('SNR:%fdB', 10*log10(snr));
三、仿真结果
1 Vivado 仿真结果
图中注意高斯噪声是窄带的,也就是每个码元周期噪声是个恒定值,码元切换时噪声变化,这符合信噪比的确切定义。
可以看到 输出比特流和输入比特流形状一致,只是有延迟。QPSK解调的码字和发送的码字也一致。
2 MATLAB分析结果
可以看到,实际的误码率低于理论误码率。图中为10dB仿真。Vivado中设计的信噪比通过MATLAB分析也是正确的