ADC采样信号RMS测量值的Verilog实现

  术语“RMS”代表“Root-Mean-Squared”。大多数书籍将此定义为“产生与等效直流电源相同的加热效果的交流电量”,或者沿着这些线路类似的东西,但RMS值不仅仅是这个。 RMS值是瞬时值的平方函数的平均值(平均值)的平方根。
  笔者的印象中第一次接触到交流电是初中,具体是初二还是初三就不太清楚了。交流电动势的表达式为e=E(m)sinωt,其中E(m)为交流电动势的最大值,那么交流电动势的有效值为 E=E(m)/√2
  同理得交流电压的有效值和交流电流的有效值分别为:
    U = U(m)/√2
    I   = I(m)/√2
  以上的方法是以前中学课本里头理想情况下计算正弦余弦的有效值方法。而在实际的ADC采样中,采集到的信号可能并不是标准的正弦余弦信号,甚至可能是些杂乱的噪声信号。根据有效值的基本定义:周期量在一个周期内的均方根值。可以用以下的公式表示:

        

  根据该公式可以把ADC采集到的信号直接用代码计算出来

  1 //**************************************************************************
  2 // *** file name      : RMS_measure.v
  3 // *** version        : 1.0
  4 // *** Description    : ADC RMS measure
  5 // *** Blogs          : https://www.cnblogs.com/WenGalois123/
  6 // *** Author         : Galois_V
  7 // *** Date           : 2022.10.26
  8 // *** Changes        : Initial
  9 //**************************************************************************
 10 `timescale 1ns/1ps
 11 module RMS_measure
 12 #(
 13     parameter                    DWIDTH = 18
 14 )
 15 (
 16     input                        i_sys_clk          ,
 17     input                        i_sys_rstn         ,
 18     input         [DWIDTH-1:0]   i_adc_data         ,
 19     input                        i_adc_valid        ,
 20     input                        i_measure_enable   ,
 21     output reg    [31:0]         o_adc_data_cnt     ,
 22     output reg    [63:0]         o_adc_square_sum   ,
 23     output reg    [47:0]         o_adc_sum          ,
 24     output reg                   o_adc_sum_valid
 25 );
 26     wire  [DWIDTH+1:0]           w_adc_data         ;
 27     wire  [2*(DWIDTH+1)+1:0]     w_mult_data        ;
 28     wire                         w_adc_add_en       ;
 29     wire                         w_adc_notend       ;
 30     wire                         w_square_overflow  ;
 31     
 32     reg    signed    [DWIDTH+1:0]         r_adc_data             ;
 33     reg    signed    [2*(DWIDTH+1)+1:0]   r_mult_data            ;
 34     reg              [5:0]                r_adc_end_detection    ;
 35     
 36     assign w_adc_data        = (i_adc_valid & i_measure_enable) ? {{2{i_adc_data[DWIDTH-1]}},i_adc_data} : 'd0;
 37     assign w_square_overflow = &o_adc_square_sum[63:54];
 38     assign w_adc_notend      = i_measure_enable && w_square_overflow;
 39     assign w_adc_add_en      = i_adc_valid && w_adc_notend;
 40 /******************************************************************************\
 41 Calculate sum of squares
 42 \******************************************************************************/                                    
 43     always@(posedge i_sys_clk)
 44     begin
 45         if(~i_sys_rstn)
 46         begin
 47             r_adc_data  <= 'd0;
 48             r_mult_data <= 'd0;
 49         end
 50         else
 51         begin
 52             r_adc_data  <= w_adc_data;
 53             r_mult_data <= r_adc_data * r_adc_data;
 54         end
 55     end
 56     
 57     assign w_mult_data = r_mult_data;
 58     
 59     always@(posedge i_sys_clk)
 60     begin
 61         if(~i_sys_rstn)
 62         begin
 63             o_adc_square_sum <= 'd0;
 64         end
 65         else
 66         begin
 67             o_adc_square_sum <= o_adc_square_sum + w_mult_data;
 68         end
 69     end
 70 /******************************************************************************\
 71 Count ADC points
 72 \******************************************************************************/
 73     always@(posedge i_sys_clk)
 74     begin
 75         if(~i_sys_rstn)
 76         begin
 77             o_adc_data_cnt <= 'd0;
 78         end
 79         else if(w_adc_add_en)
 80         begin
 81             o_adc_data_cnt <= o_adc_data_cnt + 1'b1;
 82         end
 83     end
 84 /******************************************************************************\
 85 Statistical ADC accumulation sum
 86 \******************************************************************************/
 87     always@(posedge i_sys_clk)
 88     begin
 89         if(~i_sys_rstn)
 90         begin
 91             o_adc_sum <= 'd0;
 92         end
 93         else if(w_adc_add_en)
 94         begin
 95             o_adc_sum <= o_adc_sum + {{(47-DWIDTH-1){w_adc_data[DWIDTH+1]}},w_adc_data};
 96         end
 97     end
 98 /******************************************************************************\
 99 Output the effective signal of the result to ensure the stability of the result
100 \******************************************************************************/
101     always@(posedge i_sys_clk)
102     begin
103         if(~i_sys_rstn)
104         begin
105             r_adc_end_detection <= 'd0;
106         end
107         else
108         begin
109             r_adc_end_detection <= {r_adc_end_detection[4:0],w_adc_notend};
110         end
111     end
112     
113     always@(posedge i_sys_clk)
114     begin
115         if(~i_sys_rstn)
116         begin
117             o_adc_sum_valid <= 'd0;
118         end
119         else if(~r_adc_end_detection[4] && r_adc_end_detection[5])
120         begin
121             o_adc_sum_valid <= 1'b1;
122         end
123         else
124         begin
125             o_adc_sum_valid <= 'd0;
126         end
127     end
128     
129 endmodule

  以上代码分别算出有效时间内(i_measure_enable为时间阈值设置信号)ADC信号的点数,平方和以及ADC的累加值。计算出的这些值可以通过axi4_lite总线的传给soc,对数据根据公式进行浮点型计算得出信号的平均值,有效值。

posted on 2022-10-28 10:25  Galois_V  阅读(1386)  评论(0编辑  收藏  举报