Design and implementation of pulse parameter measuring instrument (2) Frequency measurement by frequency meter

Frequency measurement is a very common and classic problem in FPGAs, because EDA technology can be used to measure frequencies ranging from millihertz to hundreds of megahertz.

Common frequency measurement methods are: direct measurement, equal period, and equal accuracy.

The principle of direct frequency measurement method: within a certain period of time, count the pulses of the signal, and then calculate how many pulses are in 1s, which is how many Hz. It is conceivable that if the start of counting is not from the rising or falling edge of the square wave Counting, but starting counting at the high level duration or low level duration, theoretical analysis knows that there must be errors.

Equal period method: Measure the time of a pulse, and one-half of the period is the frequency.

Equal precision method: The equal precision frequency measurement method eliminates the counting error by synchronizing the gate signal with the measured signal Fx. The principle circuit is shown in Figure 1. The gate signal G is used as the input of the edge D flip-flop, and the measured signal When Fx is used as the clock pulse of D flip-flop, the new gate signal SG output by D flip-flop is synchronized with Fx

Figure 1

The working principle of the equal-precision frequency measurement method is: when the gate signal G jumps to a high level, only when the rising edge of the measured signal Fx arrives, the new gate signal SG output by the D flip-flop can jump to a high level; When the gate signal G jumps to a low level, the new gate signal SG output by the D flip-flop can also jump to a low level only when the rising edge of the measured signal Fx arrives. Therefore, the new gate signal SG output by the D flip-flop is strictly synchronized with the measured signal Fx, so when the new gate signal is used to control the counter, the counting error can be eliminated. However, since the action time of the new gate signal SG is controlled by the measured signal Fx, although the action time of the original gate signal G is 1 second, the action time of the new gate signal is not necessarily 1 second, so the count in the counter N The value does not represent the frequency value of the signal under test. The improved method is to add another set of AND gates and counters, count the measured signal Fx and a standard frequency signal Fs at the same time within the action time of the new gate signal SG, and apply the relationship that the counting time of the two counters is exactly the same to calculate Get the frequency value of the signal under test.

The calculation principle of the measured signal frequency of the frequency measurement method with equal precision is shown in Figure 2. If the action time of the new gate signal SG is recorded as TD, the cycle of the standard frequency signal Fs is recorded as Ts, and the cycle of the measured signal Fx is recorded as Tx, the counting values ​​of the standard frequency signal and the measured signal are respectively recorded in TD time N, and N;, then the action time TD of the gate signal SG can be accurately expressed as

TD=Nx×Tx

Figure II

The equal-precision method is more suitable for measuring high-frequency signals, but the subject requires 10HZ-2MHZ, and the span is relatively large, so I choose to use equal-period for low-frequency, and equal-precision for high-frequency, and use buttons to switch display.

The isocycle code is as follows:

 always @ (posedge clk or negedge rst_n)
    begin
      if (!rst_n)
        begin
        low_cnt <= 25'd0;
        high_cnt <= 25'd0;
        low_time <= 25'd0;
        high_time <= 25'd0;
        state <= high_state;
        end
      else
      begin
        case (state)
          high_state :begin                   high_cnt <= 25'd0;                 begin               else                 end                   state <= high_state;                   high_cnt <= high_cnt + 1'b1;                 begin
              if (wave == 1'b1) //judgment input is high level







                  high_time <= high_cnt;
                  state <= low_state;
                end
            end
            
          low_state : begin
              if (wave == 1'b0)  //判断输入为低电平
                begin
                  low_cnt <= low_cnt + 1'b1;
                  state <= low_state;
                end
              else
                begin
                  low_cnt <= 25'd0;
                  low_time <= low_cnt;
                  state <= high_state;
                end
            end
          default : state <= low_state;
          endcase
      end
    end

Frequency: assign freq = 1_000_000_000/(low_time * 20 + high_time * 20);  

Explain this formula, because the onboard crystal oscillator is 50MHZ, the period is 20ns, the denominator is ns, the numerator is also ns, the calculated frequency unit is HZ, so the numerator 1s=1_000_000_000ns.

At the same time, it is also very easy to find the duty cycle: assign duty_cycle = (high_time * 100)/(high_time + low_time);

The precision needs to be explained in detail, you can go to the punctual atomic code or refer to other big guys

module cymometer
   #(parameter CLK_FS = 32'd50_000_000) // reference clock frequency value
    (   
        input clk_fs , // reference clock signal
        input rst_n , // reset signal


        input clk_fx , // the measured clock signal
        output reg [20:0] data_fx // the measured clock frequency output
);


localparam MAX = 10'd64; // Define the maximum bit width of fs_cnt and fx_cnt
localparam GATE_TIME = 16'd5_000; // Gating time setting


reg gate ; // gating signal
reg gate_fs ; // gating signal synchronized to the reference clock
reg gate_fs_r ; // register for synchronizing the gate signal
reg gate_fs_d0 ; // used for collecting the falling edge of the reference clock
reg gate_fs_d1 ; // 
reg gate_fx_d0 ; // used to capture the falling edge of the gate under test
reg gate_fx_d1 ; // 
reg [ 15:0] gate_cnt ; // gate count
reg [MAX-1:0] fs_cnt ; // gate time The count value of the internal reference clock
reg [MAX-1:0] fs_cnt_temp ; // the temporary value of fs_cnt
reg [MAX-1:0] fx_cnt ; // the count value of the clock under test within the gating time
reg [MAX-1:0 ] fx_cnt_temp ; // fx_cnt temporary value


wire neg_gate_fs; // The falling edge of the gate control signal under the reference clock
wire neg_gate_fx; // The falling edge of the gate control signal under the measured clock

//Edge detection, capture signal falling edge
assign neg_gate_fs = gate_fs_d1 & (~gate_fs_d0);
assign neg_gate_fx = gate_fx_d1 & (~gate_fx_d0);

//Gating signal counter, counting using the clock under test
always @(posedge clk_fx or negedge rst_n) begin
    if(!rst_n)
        gate_cnt <= 16'd0; 
    else if(gate_cnt == GATE_TIME + 5'd20)
        gate_cnt <= 16 'd0;
    else
        gate_cnt <= gate_cnt + 1'b1;
end

//Gating signal, the pull-up time is GATE_TIME measured clock cycles
always @(posedge clk_fx or negedge rst_n) begin
    if(!rst_n)
        gate <= 1'b0;
    else if(gate_cnt < 4'd10)
        gate <= 1 'b0;     
    else if(gate_cnt < GATE_TIME + 4'd10)
        gate <= 1'b1;
    else if(gate_cnt <= GATE_TIME + 5'd20)
        gate <= 1'b0;
    else 
        gate <= 1'b0;
end

//Synchronize the gating signal to the reference clock
always @(posedge clk_fs or negedge rst_n) begin
    if(!rst_n) begin
        gate_fs_r <= 1'b0;
        gate_fs <= 1'b0;
    end
    else begin
        gate_fs_r <= gate;
        gate_fs < = gate_fs_r;
    end
end

//Beat the falling edge of the gating signal (under the clock under test)
always @(posedge clk_fx or negedge rst_n) begin
    if(!rst_n) begin
        gate_fx_d0 <= 1'b0;
        gate_fx_d1 <= 1'b0;
    end
    else begin
        gate_fx_d0 <= gate;
        gate_fx_d1 <= gate_fx_d0;
    end
end

//Beat the falling edge of the gating signal (under the reference clock)
always @(posedge clk_fs or negedge rst_n) begin
    if(!rst_n) begin
        gate_fs_d0 <= 1'b0;
        gate_fs_d1 <= 1'b0;
    end
    else begin
        gate_fs_d0 <= gate_fs;
        gate_fs_d1 <= gate_fs_d0;
    end
end

// Count the clock under test always within the gating time
@(posedge clk_fx or negedge rst_n) begin
    if(!rst_n) begin
        fx_cnt_temp <= 32'd0;
        fx_cnt <= 32'd0;
    end
    else if(gate)
        fx_cnt_temp <= fx_cnt_temp + 1'b1;
    else if(neg_gate_fx) begin
        fx_cnt_temp <= 32'd0;
        fx_cnt <= fx_cnt_temp;
    end
end

// Count the reference clock within the gate control time
always @(posedge clk_fs or negedge rst_n) begin
    if(!rst_n) begin
        fs_cnt_temp <= 32'd0;
        fs_cnt <= 32'd0;
    end
    else if(gate_fs)
        fs_cnt_temp <= fs_cnt_temp + 1'b1;
    else if(neg_gate_fs) begin
        fs_cnt_temp <= 32'd0;
        fs_cnt <= fs_cnt_temp;
    end
end

// Calculate the frequency of the signal under test
always @(posedge clk_fs or negedge rst_n) begin
    if(!rst_n) begin
        data_fx <= 32'd0;
    end
    else if(gate_fs == 1'b0)
        data_fx <= (CLK_FS* fx_cnt ) / fs_cnt ;
end

endmodule 

So far the first question is done.

Guess you like

Origin blog.csdn.net/qq_52838784/article/details/122734117