FM的正交解调法
1.FM的模拟调制过程
FM信号是一种频率调制信号,其携带的信息保存在其信号的频率中,通过改变载波的频率来实现基带数据的传输。
其函数表达式如下:
\[s(t) = A*cos(w_c*t + K_f*\int m(\tau) d\tau)
\]
其中:
A
:表示载波幅度。
\(m(\tau)\):表示基带信号。
\(w_c\):表示载波信号角度增量。
\(K_f\):是调频灵敏度。
正交调制法公式如下:
\[\begin{array}{3}
I(t) = cos(K_f*\int m(\tau) d\tau) \\
Q(t) = sin(K_f*\int m(\tau) d\tau) \\
s(t) = A*(I(t)*cos(w_c*t) - Q(t)*sin(w_c*t))
\end{array}
\]
2.FM的数字正交解调
原理:
4.FPGA解调
逻辑代码:
module fm_demod(
input clk ,
input rst ,
//解调参数
input i_valid ,
input [15:0] i_data_i ,
input [15:0] i_data_q ,
output reg o_rdy ,
output reg [15:0] o_data
);
wire fm_valid ;
wire [23:0] fm_i ;
wire [23:0] fm_q ;
wire fm_rdy ;
wire [47 : 0] m_axis_dout_tdata ;
wire [15:0] fm_phase ;
//AM 解调
assign fm_valid = i_valid ;
assign fm_i = {{8{i_data_i[15]}},i_data_i} ;
assign fm_q = {{8{i_data_q[15]}},i_data_q} ;
cordic_translate cordic_translate (
.aclk (clk ), // input wire aclk
.s_axis_cartesian_tvalid (fm_valid ), // input wire s_axis_cartesian_tvalid
.s_axis_cartesian_tdata ({fm_i,fm_q} ), // input wire [47 : 0] s_axis_cartesian_tdata
.m_axis_dout_tvalid (fm_rdy ), // output wire m_axis_dout_tvalid
.m_axis_dout_tdata (m_axis_dout_tdata ) // output wire [47 : 0] m_axis_dout_tdata
);
reg [15:0] fm_phase_d;
assign fm_phase = m_axis_dout_tdata[24 +:16];
always @(posedge clk)begin
if(rst)begin
o_rdy <= 0;
o_data <= 0;
o_data <= 0;
end
else begin
o_rdy <= fm_rdy;
fm_phase_d <= fm_phase[15:0];
o_data <= fm_phase[15:0] - fm_phase_d;
end
end
endmodule
仿真代码:
module tb_fm_demod();
reg clk;
reg rst;
initial begin
clk <= 0;
rst <= 1;
#300
rst <= 0;
end
always #(100/2) clk <=~clk;
reg valid;
reg [15:0] din_i;
reg [15:0] din_q;
wire o_rdy ;
wire [15:0] o_data ;
fm_demod fm_demod(
.clk (clk),
.rst (rst),
.i_valid (valid),
.i_data_i (din_i),
.i_data_q (din_q),
.o_rdy (o_rdy ),
.o_data (o_data )
);
integer file_rd; //定义数据读指针
integer flag;
initial begin //打开读取和写入的文件,这里的路径要对
file_rd = $fopen("FM.txt","r");
end
reg [15:0] cnt;
always @(posedge clk)begin
if(rst)begin
din_i <= 0;
din_q <= 0;
cnt <= 0;
valid <= 0;
end
else if(cnt <= 1000)begin
valid <= 1;
flag = $fscanf(file_rd,"%d %d",din_i,din_q);
cnt <= cnt + 1;
end
else begin
$fclose(file_rd);
$stop();
end
end
endmodule
仿真结果: