0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

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

jf_78858299 来源:硬禾学堂 作者:苏老师 2023-04-25 11:18 次阅读

使用的平台:

图片

多数FPGA芯片上没有ADC的功能,而一些应用则需要用到ADC对一些模拟信号,比如直流电压等进行量化,有没有特别简单、低成本的实现方法呢?

在要求转换速率不高的情况下,完全可以借助一颗高速比较器(成本只有几毛钱)来实现对模拟信号的量化,Lattice的官网上一篇文章就介绍了如何制作一个简易的Sigma Delta ADC,如果FPGA能够提供LVDS的接口,连外部的高速比较器都可以省掉。由于我们的小脚丫FPGA核心模块在设计的时候没有考虑到LVDS的应用场景,所以还是需要搭配一个高速的比较器来实现Lattice官网上推荐的简易Sigma Delta ADC的功能。

让小脚丫FPGA通过锁相环PLL运行于120MHz的主时钟(还可以更高,提速到240MHz、360MHz都应该没有问题),测试1KHz以内的模拟信号是没有问题的。

Lattice的官网上就可以下载到简易Sigma Delta ADC的Verilog源代码,可以非常方便地用在其它品牌、其它系列的FPGA上。

下面的截图就是采用120MHz的主时钟实现的对1KHz模拟信号的采样,并通过DDS/DAC输出,口袋仪器M2000采集并显示的模拟信号波形。

图片

M2000口袋仪器显示的1KHz的波形

工作原理

详细的工作原理介绍可以参考项目https://www.eetree.cn/project/detail/255 及项目页面中的参考资料,在这里以几幅图片来示例一下。

图片

简易Sigma Delta ADC的工作原理

图片

直接连接 - 被测模拟信号的幅度范围为0-3.3V

图片

通过电阻分压网络输入,并在比较器+端提供参考电压,则被采集模拟信号的电压变化范围可以扩展

图片

简易Sigma Delta ADC的性能与逻辑电路的工作频率

图片

在不同的FPGA平台上消耗的逻辑资源

以下就是我们的电赛综合训练板上简易Sigma Delta ADC部分的电路连接

图片

核心代码:

顶层调用代码:

wire [7:0] sd_adc_out; // sigma delta adc data output


wire sample_rdy;    // flag for adc conversion


ADC_top my_adc(.clk_in(clk_hs),.rstn(1'b1),.digital_out(sd_adc_out), .analog_cmp(comp_in),.analog_out(ad_pwm),.sample_rdy(sample_rdy));


assign dac_data = sd_adc_out;
assign dac_clk = clk_hs; //120MHz generated by PLL

Sigma Delta ADC顶层程序

//*********************************************************************
//
//  ADC Top Level Module
//
//*********************************************************************


module ADC_top (
  clk_in,
  rstn,
  digital_out,
  analog_cmp,  
  analog_out,
  sample_rdy);


parameter 
ADC_WIDTH = 8,              // ADC Convertor Bit Precision
ACCUM_BITS = 10,            // 2^ACCUM_BITS is decimation rate of accumulator
LPF_DEPTH_BITS = 3,         // 2^LPF_DEPTH_BITS is decimation rate of averager
INPUT_TOPOLOGY = 1;         // 0: DIRECT: Analog input directly connected to + input of comparitor
                            // 1: NETWORK:Analog input connected through R divider to - input of comp.


//input ports
input  clk_in;        // 62.5Mhz on Control Demo board
input  rstn;   
input  analog_cmp;      // from LVDS buffer or external comparitor


//output ports
output  analog_out;         // feedback to RC network
output  sample_rdy;
output [7:0] digital_out;   // connected to LED field on control demo bd.



//**********************************************************************
//
//  Internal Wire & Reg Signals
//
//**********************************************************************
wire              clk;
wire              analog_out_i;
wire              sample_rdy_i;
wire [ADC_WIDTH-1:0]      digital_out_i;
wire [ADC_WIDTH-1:0]      digital_out_abs;




assign clk = clk_in;


//***********************************************************************
//
//  SSD ADC using onboard LVDS buffer or external comparitor
//
//***********************************************************************
sigmadelta_adc #(
  .ADC_WIDTH(ADC_WIDTH),
  .ACCUM_BITS(ACCUM_BITS),
  .LPF_DEPTH_BITS(LPF_DEPTH_BITS)
  )
SSD_ADC(
  .clk(clk),
  .rstn(rstn),
  .analog_cmp(analog_cmp),
  .digital_out(digital_out_i),
  .analog_out(analog_out_i),
  .sample_rdy(sample_rdy_i)
  );


assign digital_out_abs = INPUT_TOPOLOGY ? ~digital_out_i : digital_out_i;  


//***********************************************************************
//
//  output assignments
//
//***********************************************************************


assign digital_out   = ~digital_out_abs;   // invert bits for LED display 
assign analog_out    =  analog_out_i;
assign sample_rdy    =  sample_rdy_i;


endmodule

Sigma Delta ADC主程序

//*********************************************************************
//
//  SSD Top Level Module
//
//*********************************************************************


module sigmadelta_adc (
  clk,                    
  rstn,                   
  digital_out,            
  analog_cmp,              
  analog_out,             
  sample_rdy);            


parameter 
ADC_WIDTH = 8,              // ADC Convertor Bit Precision
ACCUM_BITS = 10,            // 2^ACCUM_BITS is decimation rate of accumulator
LPF_DEPTH_BITS = 3;         // 2^LPF_DEPTH_BITS is decimation rate of averager


//input ports
input  clk;                            // sample rate clock
input  rstn;                           // async reset, asserted low
input  analog_cmp ;                    // input from LVDS buffer (comparitor)


//output ports
output  analog_out;                     // feedback to comparitor input RC circuit
output  sample_rdy;                     // digital_out is ready
output [ADC_WIDTH-1:0]  digital_out;    // digital output word of ADC


//**********************************************************************
//
//  Internal Wire & Reg Signals
//
//**********************************************************************
reg                         delta;          // captured comparitor output
reg [ACCUM_BITS-1:0]      sigma;          // running accumulator value
reg [ADC_WIDTH-1:0]          accum;          // latched accumulator value
reg [ACCUM_BITS-1:0]      counter;        // decimation counter for accumulator
reg              rollover;       // decimation counter terminal count
reg              accum_rdy;      // latched accumulator value 'ready' 


//***********************************************************************
//
//  SSD 'Analog' Input - PWM
//
//  External Comparator Generates High/Low Value
//
//***********************************************************************


always @ (posedge clk)
begin
    delta <= analog_cmp;        // capture comparitor output
end


assign analog_out = delta;      // feedback to comparitor LPF


//***********************************************************************
//
//  Accumulator Stage
//
//  Adds PWM positive pulses over accumulator period
//
//***********************************************************************


always @ (posedge clk or negedge rstn)
begin
  if( ~rstn ) 
    begin
    sigma       <= 0;
    accum       <= 0;
    accum_rdy   <= 0;
    end else begin
        if (rollover) begin
            // latch top ADC_WIDTH bits of sigma accumulator (drop LSBs)
            accum <= sigma[ACCUM_BITS-1:ACCUM_BITS-ADC_WIDTH];
            sigma <= delta;         // reset accumulator, prime with current delta value
        end else begin
            if (&sigma != 1'b1)         // if not saturated
                sigma <= sigma + delta; // accumulate 
        end
        accum_rdy <= rollover;     // latch 'rdy' (to align with accum)
    end
end


//***********************************************************************
//
//  Box filter Average
//
//  Acts as simple decimating Low-Pass Filter
//
//***********************************************************************


box_ave #(
    .ADC_WIDTH(ADC_WIDTH),
    .LPF_DEPTH_BITS(LPF_DEPTH_BITS))
box_ave (
    .clk(clk),
    .rstn(rstn),
    .sample(accum_rdy),
    .raw_data_in(accum),
    .ave_data_out(digital_out),
    .data_out_valid(sample_rdy)
);


//************************************************************************
//
// Sample Control - Accumulator Timing
//  
//************************************************************************


always @(posedge clk or negedge rstn)
begin
  if( ~rstn ) begin
    counter <= 0;
    rollover <= 0;
    end
  else begin
    counter <= counter + 1;       // running count
    rollover <= &counter;         // assert 'rollover' when counter is all 1's
    end
end
endmodule
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • FPGA
    +关注

    关注

    1603

    文章

    21331

    浏览量

    593588
  • 芯片
    +关注

    关注

    447

    文章

    47838

    浏览量

    409680
  • adc
    adc
    +关注

    关注

    95

    文章

    5654

    浏览量

    539614
收藏 人收藏

    评论

    相关推荐

    proteus中可以用什么组合来实现具有激光测距传感功能

    proteus中可以用什么组合来实现具有激光测距传感功能
    发表于 05-20 14:58

    可以用什么替代adc0809,不可以用adc芯片,不可以使用现成模块,不可以编写程序

    可以用什么替代adc0809,不可以用adc芯片,不可以使用现成模块,不可以编写程序
    发表于 05-06 09:51

    请问设计数模混合系统是否可以用ADUM1250这款芯片?

    您好,我想请问当我设计数模混合系统时,数字地与模拟地分开,数字信号跨平面时是否可以用这款芯片?因为可能有双向信号,所以ADUM1400那种就不行了。 另外看了ADI的些技术文档,
    发表于 08-19 06:29

    如何用STM32F407实现模拟比较功能

    STM32F407没有独立的模拟比较端口,如何能实现可编程的模拟比较
    发表于 11-26 16:13

    如何用STM32F407实现可编程的模拟比较功能

    STM32F407没有独立的模拟比较端口,如何能实现可编程的模拟比较
    发表于 11-28 14:00

    STM32F303VCT6比较只有三可以用

    STM32F303VCT6共有7比较,为何只有COMP1、COMP2、COMP7这三可以用
    发表于 02-13 07:13

    怎么利用FPGA和CPLD数字逻辑实现ADC

    数字系统的设计人员擅长在其印制电路板FPGA和CPLD将各种处理、存储和标准的功能元件粘
    发表于 08-19 06:15

    如何利用FPGA实现高频率ADC

    数字系统的设计人员擅长在其印制电路板FPGA和CPLD将各种处理、存储和标准的功能元件粘
    发表于 09-19 06:18

    ADC多路扫描,采用DMA传输,ADC可以用定时触发吗?

    可以用定时触发ADC,配置好DMA连续转换就可以
    发表于 02-23 15:52

    可以用FPGA做些什么

    我刚买了新的NEXYS4 DDR板,我已经安装并使用了Vivado套件。我的问题是我可以用FPGA做些什么?我是名计算机/电气学生,我之所以采用这种逻辑与实验课是因为我已经参加了我学校提供的常规
    发表于 05-05 07:28

    可以用运放和分立的外接晶体管实现恒流电路吗?

    运放和分立的外接晶体管就可以实现
    发表于 04-08 06:24

    可以用STM32实现什么?为什么使用STM32而不是8051

    你问,如何系统地入门学习STM32?本身就是错误的问题。假如你会使用8051 , 会写C语言,那么STM32本身并不需要刻意的学习。你要考虑的是, 我可以用STM32实现
    发表于 02-25 06:43

    应用笔记(三)| 运用DMA 功能实现高级定时ADC 的同步触发采样

    ATIM 的配置ATIM 包含 16 位的计数 / 定时和 7 比较单元。7
    发表于 07-08 17:02

    arduinopwm做dac输出时,可以用adc校准精度吗?

    arduinopwm做dac输出时,可以用adc校准精度吗 怎么实现?最好用代码说明
    发表于 11-03 06:42

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

    多数FPGA芯片上没有ADC功能,而一些应用则需要用到ADC对一些模拟信号,比如直流电压等进行量化,有没有特别简单、低成本的实现方法呢?
    的头像 发表于 04-25 11:19 952次阅读