FPGA上可以用一个比较器实现ADC的功能?2

电子说

1.2w人已加入

描述

数字低通滤波器模块,做平滑滤波

//*********************************************************************
//
//  'Box' Average 
//
//  Standard Mean Average Calculation
//   Can be modeled as FIR Low-Pass Filter where 
//   all coefficients are equal to '1'.
//
//*********************************************************************


module box_ave (
  clk,
  rstn,
  sample,
  raw_data_in,
  ave_data_out,
    data_out_valid);


parameter 
ADC_WIDTH = 8,        // ADC Convertor Bit Precision
LPF_DEPTH_BITS = 4;         // 2^LPF_DEPTH_BITS is decimation rate of averager


//input ports
input  clk;                                // sample rate clock
input  rstn;                              // async reset, asserted low
input  sample;                        // raw_data_in is good on rising edge, 
input  [ADC_WIDTH-1:0]  raw_data_in;    // raw_data input


//output ports
output [ADC_WIDTH-1:0]  ave_data_out;    // ave data output
output data_out_valid;                      // ave_data_out is valid, single pulse


reg [ADC_WIDTH-1:0]  ave_data_out;    
//**********************************************************************
//
//  Internal Wire & Reg Signals
//
//**********************************************************************
reg [ADC_WIDTH+LPF_DEPTH_BITS-1:0]      accum;          // accumulator
reg [LPF_DEPTH_BITS-1:0]                count;          // decimation count
reg [ADC_WIDTH-1:0]            raw_data_d1;    // pipeline register


reg sample_d1, sample_d2;                               // pipeline registers
reg result_valid;                                       // accumulator result 'valid'
wire accumulate;                                        // sample rising edge detected
wire latch_result;                                      // latch accumulator result


//***********************************************************************
//
//  Rising Edge Detection and data alignment pipelines
//
//***********************************************************************
always @(posedge clk or negedge rstn)
begin
  if( ~rstn ) begin
    sample_d1 <= 0;  
    sample_d2 <= 0;
        raw_data_d1 <= 0;
    result_valid <= 0;
  end else begin
    sample_d1 <= sample;                // capture 'sample' input
    sample_d2 <= sample_d1;             // delay for edge detection
    raw_data_d1 <= raw_data_in;       // pipeline 
    result_valid <= latch_result;    // pipeline for alignment with result
  end
end


assign    accumulate = sample_d1 && !sample_d2;      // 'sample' rising_edge detect
assign    latch_result = accumulate && (count == 0);  // latch accum. per decimation count


//***********************************************************************
//
//  Accumulator Depth counter
//
//***********************************************************************
always @(posedge clk or negedge rstn)
begin
  if( ~rstn ) begin
    count <= 0;    
  end else begin
      if (accumulate)  count <= count + 1;         // incr. count per each sample
  end
end




//***********************************************************************
//
//  Accumulator
//
//***********************************************************************
always @(posedge clk or negedge rstn)
begin
  if( ~rstn ) begin
    accum <= 0;  
  end else begin
        if (accumulate)
            if(count == 0)                      // reset accumulator
            accum <= raw_data_d1;           // prime with first value
            else
                accum <= accum + raw_data_d1;   // accumulate
  end  
end

//***********************************************************************
//
//  Latch Result
//
//  ave = (summation of 'n' samples)/'n'  is right shift when 'n' is power of two
//
//***********************************************************************
always @(posedge clk or negedge rstn)
begin
  if( ~rstn ) begin
        ave_data_out <= 0;
    end else if (latch_result) begin            // at end of decimation period...
        ave_data_out <= accum >> LPF_DEPTH_BITS;    // ... save accumulator/n result
    end
end


assign data_out_valid = result_valid;       // output assignment


endmodule

有FPGA的小朋友不妨可以试一下,只需要搭配一颗比较器、一个电阻R、一个电容C,只需要FPGA的两根管脚,你就可以拥有ADC的功能了。

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分