Verilog的QPSK解调器,采用下变频costas环和Gardner环的的代码
时间: 2024-05-02 10:20:48 浏览: 75
costas.rar_costas 环_costas环_verilog载波_同步 vhdl_同步载波
5星 · 资源好评率100%
以下是Verilog的QPSK解调器代码,使用下变频Costas环和Gardner环:
```
module qpsk_demod(input clk, input rst, input [7:0] i_data, input [7:0] q_data, output reg [7:0] data_out);
reg [7:0] i_signal, q_signal, i_delayed, q_delayed, i_early, i_late, q_early, q_late, i_error, q_error;
reg [7:0] i_prev, q_prev, i_prev2, q_prev2;
reg [7:0] i_phase, q_phase;
reg [1:0] phase_select;
//Down conversion
reg [7:0] cos_out, sin_out;
reg [7:0] cos_delayed, sin_delayed;
//Costas Loop
reg [7:0] i_filtered, q_filtered;
reg [7:0] i_phase_error, q_phase_error;
reg [7:0] i_integrator, q_integrator;
reg [7:0] i_error_filtered, q_error_filtered;
//Gardner Loop
reg [7:0] i_early_filtered, q_early_filtered, i_late_filtered, q_late_filtered;
reg [7:0] i_early_error, q_early_error, i_late_error, q_late_error;
reg [7:0] i_error_diff, q_error_diff;
reg [7:0] i_error_integrator, q_error_integrator;
reg [7:0] i_error_delayed, q_error_delayed;
reg [7:0] i_output, q_output;
parameter PHASE_0 = 0, PHASE_PI_2 = 1, PHASE_PI = 2, PHASE_3_PI_2 = 3;
initial begin
i_prev <= 0;
q_prev <= 0;
i_prev2 <= 0;
q_prev2 <= 0;
i_phase <= 0;
q_phase <= 0;
phase_select <= PHASE_0;
i_integrator <= 0;
q_integrator <= 0;
i_error_filtered <= 0;
q_error_filtered <= 0;
i_error_integrator <= 0;
q_error_integrator <= 0;
end
//Down conversion
always @(posedge clk) begin
cos_delayed <= cos_out;
sin_delayed <= sin_out;
cos_out <= i_data * i_signal - q_data * q_signal;
sin_out <= i_data * q_signal + q_data * i_signal;
end
//Costas Loop
always @(posedge clk) begin
i_filtered <= (cos_out + cos_delayed) / 2;
q_filtered <= (sin_out + sin_delayed) / 2;
i_phase_error <= q_filtered * i_phase - i_filtered * q_phase;
q_phase_error <= i_filtered * q_phase + q_filtered * i_phase;
i_integrator <= i_integrator + i_phase_error;
q_integrator <= q_integrator + q_phase_error;
i_error_filtered <= i_phase_error - q_integrator;
q_error_filtered <= q_phase_error + i_integrator;
end
//Gardner Loop
always @(posedge clk) begin
i_early <= i_filtered - i_error_filtered;
i_late <= i_filtered + i_error_filtered;
q_early <= q_filtered - q_error_filtered;
q_late <= q_filtered + q_error_filtered;
i_early_filtered <= (i_early + i_prev2) / 2;
i_late_filtered <= (i_late + i_prev) / 2;
q_early_filtered <= (q_early + q_prev2) / 2;
q_late_filtered <= (q_late + q_prev) / 2;
i_early_error <= i_early_filtered - i_late_filtered;
q_early_error <= q_early_filtered - q_late_filtered;
i_error_diff <= i_early_error - i_late_error;
q_error_diff <= q_early_error - q_late_error;
i_error_integrator <= i_error_integrator + i_error_diff;
q_error_integrator <= q_error_integrator + q_error_diff;
i_error_delayed <= i_error_integrator - (i_error_integrator >> 2);
q_error_delayed <= q_error_integrator - (q_error_integrator >> 2);
i_output <= i_error_delayed + i_filtered;
q_output <= q_error_delayed + q_filtered;
end
//Phase selection
always @(posedge clk) begin
case(phase_select)
PHASE_0: begin
i_signal <= 255;
q_signal <= 0;
if(i_output < 0)
phase_select <= PHASE_PI_2;
end
PHASE_PI_2: begin
i_signal <= 0;
q_signal <= 255;
if(q_output < 0)
phase_select <= PHASE_PI;
end
PHASE_PI: begin
i_signal <= -255;
q_signal <= 0;
if(i_output > 0)
phase_select <= PHASE_3_PI_2;
end
PHASE_3_PI_2: begin
i_signal <= 0;
q_signal <= -255;
if(q_output > 0)
phase_select <= PHASE_0;
end
endcase
end
//Output data
always @(posedge clk) begin
data_out <= i_prev2;
i_prev2 <= i_prev;
i_prev <= i_output;
q_prev2 <= q_prev;
q_prev <= q_output;
end
endmodule
```
阅读全文