1.算法仿真效果
本系统进行了两个平台的开发,分别是:
Vivado2019.2
Quartusii18.0+ModelSim-Altera 6.6d Starter Edition
其中Vivado2019.2仿真结果如下:
Quartusii18.0+ModelSim-Altera 6.6d Starter Edition的测试结果如下:
2.算法涉及理论知识概要
B2PSK信号与2ASK信号的时域表达式在形式上是完全相同的,所不同的只是两者基带信号s(t)的构成,一个由双极性NRZ码组成,另一个由单极性NRZ码组成。因此,求BPSK信号的功率谱密度时,也可采用与求2ASK信号功率谱密度相同的方法。
(1)当双极性基带信号以相等的概率(p=1/2)出现时,BPSK信号的功率谱仅由连续谱组成。BPSK信号的功率谱由连续谱和离散谱两部分组成。其中,连续谱取决于数字基带信号s(t)经线性调制后的双边带谱,而离散谱则由载波分量确定。
(2)BPSK的连续谱部分与2ASK信号的连续谱基本相同(仅差一个常数因子)。因此,BPSK信号的带宽、频带利用率也与2ASK信号的相同。
在数字调制中,BPSK(后面将会看到2DPSK也同样)的频谱特性与2ASK十分相似。相位调制和频率调制一样,本质上是一种非线性调制,但在数字调相中,由于表征信息的相位变化只有有限的离散取值,因此,可以把相位变化归结为幅度变化。这样一来,数字调相同线性调制的数字调幅就联系起来了,为此可以把数字调相信号当作线性调制信号来处理了。但是不能把上述概念推广到所有调相信号中去。
BPSK (Binary Phase Shift Keying)-------二进制相移键控。是把模拟信号转换成数据值的转换方式之一,利用偏离相位的复数波浪组合来表现信息键控移相方式。BPSK使用了基准的正弦波和相位反转的波浪,使一方为0,另一方为1,从而可以同时传送接受2值(1比特)的信息。
由于最单纯的键控移相方式虽抗噪音较强但传送效率差,所以常常使用利用4个相位的QPSK和利用8个相位的BPSK。
二进制相移键控(BPSK)信号进行相干解调的系统,其包括:用于从所述BPSK信号中恢复出频率为2F的载波信号(C)的装置;用于将频率为2F的所述信号注入到注入锁定振荡器(ILO)中的装置,该注入锁定振荡器的固有谐振频率为f↓[r],该f↓[r]大致等于f,该注入锁定振荡器提供用于恢复具有(θ↓[e]-k)/2相移的原始载波的差分输出(o↓[p]、o↓[n])信号,其中θ=arcsin[(f↓[r]-r)/αA↓[i]f],其中α和k是取决于所述注入锁定振荡器(ILO)中的主要非线性的类型的参数,而A↓[i]是所恢复的频率为2f的载波信号的幅值,以及用于将所述差分输出(o↓[p]、o↓[n])信号与所述输入BPSK信号的副本进行组合,以产生解调信号(DEMOD)的装置。
3.Verilog核心程序
//调制端
assign o_nz=(i_bits == 1'b1)?2'b01:2'b11;
wire[23:0]m_fir;
fir_compiler_0 uut (
.aresetn(~i_rst),
.aclk(i_clk),
.s_axis_data_tvalid(1'b1),
.s_axis_data_tready(),
.s_axis_data_tdata({o_nz[1],o_nz[1],o_nz[1],o_nz[1],o_nz[1],o_nz[1],o_nz}),
.m_axis_data_tvalid(),
.m_axis_data_tdata(m_fir)
);
assign o_fir=m_fir[23:8];
wire[31:0]m_carrier;
dds_compiler_0 uut2(
.aclk (i_clk),
.aresetn (~i_rst),
.s_axis_config_tvalid(1'b1),
.s_axis_config_tdata(32'd100000000),
.m_axis_data_tvalid(),
.m_axis_data_tdata(m_carrier),
.m_axis_phase_tvalid(),
.m_axis_phase_tdata()
);
assign o_carrier=m_carrier[15:0];
always @(posedge i_clk or posedge i_rst)
begin
if(i_rst)
begin
o_mod <= 32'd0;
end
else begin
o_mod <= $signed(o_carrier)*$signed(o_fir);
end
end
//解调端 ,不考虑载波同步
wire[31:0]m_carrier_local;
dds_compiler_0 uut3(
.aclk (i_clk),
.aresetn (~i_rst),
.s_axis_config_tvalid(1'b1),
.s_axis_config_tdata(32'd100000000),
.m_axis_data_tvalid(),
.m_axis_data_tdata(m_carrier_local),
.m_axis_phase_tvalid(),
.m_axis_phase_tdata()
);
assign o_carrier_local=m_carrier_local[15:0];
reg signed[31:0]tmps;
always @(posedge i_clk or posedge i_rst)
begin
if(i_rst)
begin
tmps <= 32'd0;
end
else begin
tmps <= $signed(o_carrier_local)*$signed(o_mod[31:16]);
end
end
assign o_dw=tmps;
wire signed[31:0]tmps2;
fiter_rrc uut4(
.i_clk (i_clk),
.i_rst (i_rst),
.i_dat (tmps[20:5]),
.o_demod(o_demod)
);
endmodule