【硬件算法】Verilog之FPGA实现信号移相法
我的学记|刘航宇的博客

【硬件算法】Verilog之FPGA实现信号移相法

刘航宇
2年前发布 /正在检测是否收录...
温馨提示:
本文最后更新于2023年04月06日,已超过687天没有更新,若内容或图片失效,请留言反馈。

实现信号移相可以用FPGA控制信号0-360度连续可调,对于高频信号(1GHZ以上)超出了FPGA工作频率还有一种办法是FPGA-》DA-》射频前端-》移相器-》阻抗匹配-》天线。本案例直接采用FPGA对数字中频信号处理(kHZ、MHZ)
本质是边沿检测与分频

现象:

图片[1] - 【硬件算法】Verilog之FPGA实现信号移相法 - 我的学记|刘航宇的博客

代码:

/*
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
© 版权声明
THE END
喜欢就支持一下吧
点赞 3 分享 赞赏
评论 抢沙发
取消