实现信号移相可以用FPGA控制信号0-360度连续可调,对于高频信号(1GHZ以上)超出了FPGA工作频率还有一种办法是FPGA-》DA-》射频前端-》移相器-》阻抗匹配-》天线。本案例直接采用FPGA对数字中频信号处理(kHZ、MHZ)
本质是边沿检测与分频
现象:
代码:
/*
Function : Phase Shift
Interface : clk_fre---unit(MHZ) din_fre---unit(KHz) phase_angle---unit(0-360 Angle)
Date: 2023/04/05
Description:
Phase shift is carried out on the input square wave.
The phase Angle unit is Angle (0-360), or the input can be greater than 360.
The system clock unit is MHz and the input signal clock is KHz.
*/
module PhaseShift(
input clk, //clk
input rst_n, //rest
input [7:0] clk_fre, //system clock frequency,MHZ
input [15:0] din_fre, //input signal clock frequency,KHZ
input [8:0] phase_angle, //phase shift angle
input din, //input signal
output reg dout //output signal
);
reg [31:0] posedge_counter;
reg [31:0] negedge_counter;
reg [31:0] delay_counter;
reg in_posedge_flg;
reg in_negedge_flg;
reg out_posedge_flg;
reg out_negedge_flg;
reg old_din;
reg init_data=1'b1;
always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
posedge_counter <= 1'b0;
negedge_counter <= 1'b0;
in_posedge_flg <= 1'b0;
in_negedge_flg <= 1'b0;
out_posedge_flg <= 1'b0;
out_negedge_flg <= 1'b0;
end
else
begin
if(~old_din & din)
in_posedge_flg = 1'b1;
if(old_din & ~din)
in_negedge_flg = 1'b1;
old_din <= din;
if(init_data)
begin
delay_counter <= ((1000000000)/din_fre*clk_fre)/360*(phase_angle%360)/1000000;
dout <= din ;
init_data <= 1'b0;
end
if(in_posedge_flg && posedge_counter <= delay_counter)
begin
posedge_counter <= posedge_counter + 1'b1 ;
out_posedge_flg <= 1'b0;
end
else
begin
posedge_counter <= 1'b0 ;
in_posedge_flg <= 1'b0 ;
if(~out_posedge_flg)
begin
dout <= 1'b1 ;
out_posedge_flg <= 1'b1 ;
end
end
if (in_negedge_flg && negedge_counter <= delay_counter)
begin
negedge_counter <= negedge_counter + 1'b1 ;
out_negedge_flg <= 1'b0 ;
end
else
begin
negedge_counter <= 1'b0 ;
in_negedge_flg <= 1'b0 ;
if(~out_negedge_flg)
begin
dout <= 1'b0 ;
out_negedge_flg <= 1'b1;
end
end
end
end
endmodule
测试代码:
`timescale 100ps/10ps //
module test_PhaseShift;
reg clk;
reg rst_n;
reg [7:0] clk_fre; //system clock frequency,MHZ
reg [15:0] din_fre ; //input signal clock frequency,KHZ
reg [8:0] phase_angle; //phase shift angle
reg din ; //input signal
wire dout ; //output signal
initial
begin
clk = 0;
din = 0;
din_fre = 4000;
phase_angle = 90;
clk_fre = 100;
rst_n = 1;
#12 rst_n = 0;
#4 rst_n = 1;
#10000 $stop; //end
end
always #5 clk = ~clk;
always #125 din = ~din;
PhaseShift u1(
.clk(clk),
.rst_n(rst_n),
.clk_fre(clk_fre),
.din_fre(din_fre),
.phase_angle(phase_angle),
.din(din),
.dout(dout)
);
endmodule
评论 (0)