FPGA对输入的信号移相


需要对MHz级别的信号移相,最开始考虑用运放,但是需要高速的运放,而且运放的压摆率还是个问题,没法做到0-360度连续可调。需要整两个以上高速运放级联,显得很繁琐,所以写了个代码,用FPGA去操作。

需要注意,移相的输出与输入有一个时钟的延时

在这里插入图片描述

在这里插入图片描述

以下是FPGA测试程序

`timescale 100ps/10ps //

module test_PhaseShift ;
reg [0:0]clk ;			//clk
reg      rst_n ;		//rest
reg [7:0]clk_fre ;		//system clock  frequency,MHZ
reg [15:0]din_fre ;		//input signal clock  frequency,MHZ
reg [8:0]phase_angle ;	//phase shift angle
reg [0:0]din ;			//input signal
wire [0:0]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 u_(
	.clk(clk),
	.rst_n(rst_n),
	.clk_fre(clk_fre),
	.din_fre(din_fre),
	.phase_angle(phase_angle),
	.din(din),
	.dout(dout)
);
endmodule

以下是FPGA程序

/*
Function : Phase Shift
Interface : clk_fre---unit(MHZ)		din_fre---unit(KHz)		phase_angle---unit(0-360 Angle)
Author:	lichangwu
Mobile phone:18862120629
Email : 18862120629@qq.com
Version : V1.0
Date: 20200708
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,MHZ
	input [8:0]phase_angle ,//phase shift angle
	input [0:0]din ,			//input signal
	output reg [0:0]dout 		//output signal
);

reg [31:0]posedge_counter;
reg [31:0]negedge_counter;
reg [31:0]delay_counter;
reg [0:0]in_posedge_flg;
reg [0:0]in_negedge_flg;
reg [0:0]out_posedge_flg;
reg [0:0]out_negedge_flg;
reg [0:0]old_din;
reg [0:0]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
  • 10
    点赞
  • 66
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值