草庐IT

ZCU106的FMC接口AD/DA(全网唯一、全网最详)

发光的沙子 2024-06-16 原文

马上就要毕业啦,好久没写文章了,今天给大家带来硕士期间的最后一次AD/DA实验的实验记录,废话少说,先看连接与视频。

  1. 连接

  1. 视频

我做的实验是AN108+FL9613的DA与AD回环测试,可能和本节教程有点出入,不过没关系,能成功就行。

实验视频

一、实验任务

采用xilinx的dds波形生成器通过DA输出模拟信号,AD采集这个模拟信号并转为数字信号。实验听起来很简单,毕竟这个属于大部分fpga厂商自带课程。但是如果没有开发经验或出现调试问题的,请耐心看完这篇文中。支持ZCU/VCU/K7等一系列xilinx官方板卡。

二、实验平台

  1. 软件:Vivado 2019.1

  1. 硬件:ZCU106(Xilinx)、FL1010(ALINX)、AN108(ALINX)

  1. FL1010介绍

FL1010可将HPC/LPC接口转为40针接口,用以连接AN108(AN108只有32针,因此有8根空闲)。连接的时候看好GND端口,对齐连接即可。

上图为FL1010的引脚图,我们只用J2端口(标黄的部分),记住VADJ(红框)这个电平,后面debug会用到。下面两图为ZCU106的FMC的HPC端口,写XDC文件时需要将J2的管脚与HPC管脚配对。

  1. AN108介绍

AN108,一个DA端口一个AD端口,现在买的都是黑色的,图中绿色的是老早以前的了,我用的黑色的。买AN108的时候会给一条两端为BNC口的连接线,将AD与DA连起来即可。

AD最大时钟频率为32MHz。DA最大时钟频率为125MHz。

上图为AN108的引脚图,共34针,与FL1010对其,接上即可。因此,实际上,写XDC文件时,只需要将用到的这18个管脚和HPC引脚配对即可。

三、实验内容

  1. 建立项目(不说)

  1. 配置时钟IP

一个50MHz用于DA,一个25MHz用于AD。

  1. ddsIP配置

参考文献:

https://blog.csdn.net/keilzc/article/details/104146629
此文讲的配置方式为system parameter,即系统配置方法

本文主要hardware parameter,即硬件配置方法

因为AN108只支持8位宽,因此这里设置8位宽。相位的化主要根据需求来定啦,16位不行就32位,这个相位决定了控制字的位宽。

比如要生成1 HMz的sin波形,则

x=1*10^6*2^16/50=1310.72≈1311=10100011111(将此值写入)。

即可。

  1. 代码

①顶层文件

`timescale 1ns / 1ps
//
// Company: 东北电力大学
// Engineer: Yang Zheng
// 
// Create Date: 2023/02/06 21:40:02
// Design Name: 
// Module Name: Main
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module Main(
    //reference clock
    input                     sys_clk_p,
    input                     sys_clk_n,
    //AD
    input   [7:0]             AD_IN,        //AD输入数据
    output                    AD_CLK,       //AD(AD9280)驱动时钟,最大支持32Mhz时钟
    //DA
    output                    DA_CLK,       //DA(AD9708)驱动时钟,最大支持125Mhz时钟
    output  [7:0]             DA_A          //输出给DA的数据
    );

wire                             clk_da_50m;
wire                             clk_ad_25m;
wire                             locked;

clk_wiz_0 uut_clk_wiz_0(
    .clk_out1(clk_da_50m),
    .clk_out2(clk_ad_25m),
    .reset(1'b0),
    .locked(locked),//信号平稳后置1
    .clk_in1_p(sys_clk_p),
    .clk_in1_n(sys_clk_n)
);

//DDS IP核例化  
//output
wire [0:0]   m_axis_data_tvalid    ;
wire [7:0]   m_axis_data_tdata     ;
wire [0:0]   m_axis_phase_tvalid   ;
wire [15:0]  m_axis_phase_tdata    ;

dds_compiler_0 dds_compiler_0_inst (
  .aclk(clk_da_50m),                             // input wire aclk
  .m_axis_data_tvalid(m_axis_data_tvalid),      // output wire m_axis_data_tvalid
  .m_axis_data_tdata(m_axis_data_tdata),        // output wire [7 : 0] m_axis_data_tdata
  .m_axis_phase_tvalid(m_axis_phase_tvalid),    // output wire m_axis_phase_tvalid
  .m_axis_phase_tdata(m_axis_phase_tdata)      // output wire [15 : 0] m_axis_phase_tdata
);

reg rst_n = 1'b1;
// -----------2、AD9708-----------// 
wire da_clk;
wire [7:0] da_data;
AD9708 AD9708_inst(
    .clk         (clk_da_50m), 
    .rst_n       (rst_n),
    .data_in     (m_axis_data_tdata),
    .da_clk      (da_clk),  
    .da_data     (da_data)
);
assign DA_CLK = da_clk;
assign DA_A = da_data;
// -----------3、AD9708-----------// 
wire ad_clk;
wire [7:0] ad_data;
AD9280 AD9280_inst(
    .clk         (clk_ad_25m), 
    .rst_n       (rst_n),
    .ad_clk      (ad_clk),  
    .ad_data     (ad_data)
);
assign AD_CLK = ad_clk;
assign ad_data = AD_IN;
endmodule

②AD9708

`timescale 1ns / 1ps
//
// Company: 东北电力大学
// Engineer: Yang Zheng
// 
// Create Date: 2023/02/06 23:48:13
// Design Name: 
// Module Name: AD9708
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module AD9708(
     input                 clk    ,  //时钟
     input                 rst_n  ,  //复位信号,低电平有效
     
     input        [7:0]    data_in,  //DDS读出的数据
     //DA芯片接口
     output                da_clk ,  //DA(AD9708)驱动时钟,最大支持125Mhz时钟
    (* MARK_DEBUG="true" *) output       [7:0]    da_data   //输出给DA的数据
    );
    //*****************************************************
    //**                    main code
    //*****************************************************
    
     //数据data_in是在clk的上升沿更新的,所以DA芯片在clk的下降沿
     //而DA实际上在da_clk的上升沿锁存数据,所以时钟取反,这样clk的下降沿相当于da_clk的上升沿
    assign  da_clk = ~clk;       
    assign  da_data = data_in;   //将读到的DDS数据
    
endmodule

③AD9280

`timescale 1ns / 1ps
//
// Company: 东北电力大学
// Engineer: Yang Zheng
// 
// Create Date: 2023/02/06 23:49:33
// Design Name: 
// Module Name: AD9280
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module AD9280(
     input                 clk         ,  //时钟
     input                 rst_n       ,  //复位信号,低电平有效
     
     input         [7:0]   ad_data     ,  //AD输入数据
     output                ad_clk         //AD(AD9280)驱动时钟,最大支持32Mhz时钟
    );
    (* MARK_DEBUG="true" *)reg [7:0] AD_IN_d0 = 'd0;
    assign ad_clk = ~clk;

    always @(posedge ad_clk or negedge rst_n) begin
        if (~rst_n) begin
            
        end
        else begin
            AD_IN_d0 <= ad_data;
        end
    end
endmodule

由于每个器件引脚不一致,XDC就不给出了,自己查引脚图即可,需要ZCU106的请联系我。

④testbench

`timescale 1ns / 1ps
//
// Company: 东北电力大学
// Engineer: Yang Zheng
// 
// Create Date: 2023/02/06 22:45:31
// Design Name: 
// Module Name: testbench
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// dds设置:控制字=输出频率*2^(相位宽度)/输入频率
//


module testbench(

    );
parameter PERIOD  = 8;


// Main Inputs
reg   clk                            = 0 ;
reg   [7:0]  AD_IN                         = 0 ;

// Main Outputs
wire  AD_CLK                               ;
wire  DA_CLK                               ;
wire  [7:0]  DA_A                          ;


initial
begin
    forever #(PERIOD/2)  clk=~clk;
end


Main  u_Main (
    .sys_clk_p               ( clk        ),
    .sys_clk_n               ( ~clk        ),
    .AD_IN                   ( AD_IN      [7:0] ),

    .AD_CLK                  ( AD_CLK           ),
    .DA_CLK                  ( DA_CLK           ),
    .DA_A                    ( DA_A       [7:0] )
);

always @(posedge clk)begin
    AD_IN <= AD_IN + 1'b1;
end

endmodule
  1. 仿真测试

这里需要注意,看波形的时候需要进行两个设置

①设置有符号整数

②选择模拟量输出

  1. 硬件实验

①综合

②点击set up debug,将两个dubug信号自动写入xdc约束文件中,然后ctrl+s保存

③生成bit

④查看ILA图像,如果AD_IN_d0信号为-1或ff没有输入,那么恭喜你,需要看第四部分了的debug内容了。

上面是一些教程或者书籍中的正常的硬件实验。他们可能调试的DA比较稳定,而我的就很不稳定哈哈哈哈(不过没关系,我的研究所用数据都是RT-lab输出的,不会存在波形这么失真的情况)。下面是我做的:

四、调试bug

  1. 如果出现上述错误,大致因为前文提到的VADJ电压不正常,采用万用表测试VADJ电压即可。

①FL1010保留3个电位测试

②ZCU106的J94为VADJ点位,J33为GND点位

  1. 安装CP210x串口驱动

  1. 安装并打开SCUI。

①ZCU106的SCUI下载地址:https://china.xilinx.com/member/forms/download/design-license.html?cid=f9c3f796-9b83-4261-bda7-7f56b9210428&filename=rdf0450-zcu106-system-controller-c-2019-1.zip

其余的,自行去xilinx官网搜索即可。

②解压,打开config.json,滑倒最下面,将CP210x改为你的驱动即可,我的是CP2108

写的接口是3,所以连接的时候用的是COM6连接的。

  1. 点击电压获取。等10s左右没有反应,则代表CP210x串口驱动没有安装好。

  1. 修正VADJ电压,两个都点一下,以后再出错,重新弄就好啦!

//---------------------------------------------23/2/9更新

可能是我使用的dds信号发生,致使DA输出口的数据不稳定。我目前做的ADDA回环实验

  1. AN108输出1 MHz的sin,FL9613可以采集到接近离谱的数据。

  1. AN108输出10 MHz的sin,FL9613可以采集到较为正弦的数据。

这个DA波形已经失真了。

  1. AN108输出45 MHz的sin,FL9613可以采集到接近离谱的数据。

这是DA输出的数据,看到已经失真了。

综上所述,主要看板子的时钟还有实验条件的干扰!!!想要调试成网上的波形,挺难的。。。。

有关ZCU106的FMC接口AD/DA(全网唯一、全网最详)的更多相关文章

  1. ruby-on-rails - Rails 3 I18 : translation missing: da. datetime.distance_in_words.about_x_hours - 2

    我看到这个错误:translationmissing:da.datetime.distance_in_words.about_x_hours我的语言环境文件:http://pastie.org/2944890我的看法:我已将其添加到我的application.rb中:config.i18n.load_path+=Dir[Rails.root.join('my','locales','*.{rb,yml}').to_s]config.i18n.default_locale=:da如果我删除I18配置,帮助程序会处理英语。更新:我在config/enviorments/devolpment

  2. ruby - 为什么 SecureRandom.uuid 创建一个唯一的字符串? - 2

    关闭。这个问题需要detailsorclarity.它目前不接受答案。想改进这个问题吗?通过editingthispost添加细节并澄清问题.关闭8年前。Improvethisquestion为什么SecureRandom.uuid创建一个唯一的字符串?SecureRandom.uuid#=>"35cb4e30-54e1-49f9-b5ce-4134799eb2c0"SecureRandom.uuid方法创建的字符串从不重复?

  3. postman接口测试工具-基础使用教程 - 2

    1.postman介绍Postman一款非常流行的API调试工具。其实,开发人员用的更多。因为测试人员做接口测试会有更多选择,例如Jmeter、soapUI等。不过,对于开发过程中去调试接口,Postman确实足够的简单方便,而且功能强大。2.下载安装官网地址:https://www.postman.com/下载完成后双击安装吧,安装过程极其简单,无需任何操作3.使用教程这里以百度为例,工具使用简单,填写URL地址即可发送请求,在下方查看响应结果和响应状态码常用方法都有支持请求方法:getpostputdeleteGet、Post、Put与Delete的作用get:请求方法一般是用于数据查询,

  4. ruby - 数组数组中的唯一元素 - 2

    我想通过内部数组中的第一个元素从数组数组中找到唯一元素。例如a=[[1,2],[2,3],[1,5]我想要类似的东西[[1,2],[2,3]] 最佳答案 uniq方法需要一个block:uniq_a=a.uniq(&:first)或者如果您想就地进行:a.uniq!(&:first)例如:>>a=[[1,2],[2,3],[1,5]]=>[[1,2],[2,3],[1,5]]>>a.uniq(&:first)=>[[1,2],[2,3]]>>a=>[[1,2],[2,3],[1,5]]或者>>a=[[1,2],[2,3],[1,5]

  5. python - 如何计算文件中唯一字符的数量? - 2

    给定一个包含各种语言字符的UTF-8文件,我如何计算它包含的唯一字符的数量,同时排除选定数量的符号(例如:“!”、“@”、"#",".")从这个算起? 最佳答案 这是一个bash解决方案。:)bash$perl-CSD-ne'BEGIN{$s{$_}++forsplit//,q(!@#.)}$s{$_}++||$c++forsplit//;END{print"$c\n"}'*.utf8 关于python-如何计算文件中唯一字符的数量?,我们在StackOverflow上找到一个类似的问题

  6. ruby - 查找字符串中唯一元素数量的最快方法 - 2

    如何以最佳方式在字符串中找到唯一元素?示例字符串格式为myString="34345667543"对/对['3','4','3','5'.....] 最佳答案 这是一个有趣的问题,因为它返回了很多几乎相似的结果,所以我做了一个简单的基准测试来决定哪个实际上是最好的解决方案:require'rubygems'require'benchmark'require'set'puts"Dothetest"Benchmark.bm(40)do|x|STRING_TEST="26263636362626218118181111232112233"

  7. ruby-on-rails - 使用 STI 为 rails 中的子模型指定唯一属性 - 2

    我计划将STIinRails与以下模型一起使用:classPromoEvent和Discount在属性方面仅存在一些差异,因此我认为STI是一个不错的选择。我不确定如何确保,例如,仅Event具有额外的image_filename属性。我知道它会在promos表中,并且它必须是NULL-able以防我插入Discount行。如何确保Discount对象对image_filename属性一无所知(即未在Discount.column_names中列出>和/或无法设置它)Event知道它吗? 最佳答案 我认为这个概念是不同的,而你的Pr

  8. ruby-on-rails - 如何在 RubyOnRails 中使用 'acts as nested set' 创建一个可排序的接口(interface) - 2

    我一直在为使用acts_as_list的模型实现一些不错的交互界面,这些界面可以对我的mRails应用程序中的列表进行排序。我有一个排序函数,在每次拖放之后使用sortable_elementscript.aculo.us函数调用并设置每条记录的位置。这是在拖放完成后处理排序的Controller操作示例:defsortparams[:documents].each_with_indexdo|id,index|Document.update_all(['position=?',index+1],['id=?',id])endend现在我正在尝试对嵌套集模型(acts_as_nested

  9. ruby-on-rails - 如何针对组合字段的唯一性对这种复杂的验证进行建模 - 2

    link有两个组件:componenta_id和componentb_id。为此,在Link模型文件中我有:belongs_to:componenta,class_name:"Component"belongs_to:componentb,class_name:"Component"validates:componenta_id,presence:truevalidates:componentb_id,presence:truevalidates:componenta_id,uniqueness:{scope::componentb_id}validates:componentb_id

  10. ruby 集不是唯一的 - 2

    出于某种原因,以下代码产生了一个具有重复值的集合。我不确定ruby​​中数组的唯一性是如何定义的,所以也许这在某种程度上是可以预料的?require'set'xs=[1,2,3]xss=Set.new[]xs.eachdo|x|xss.mergexss.to_a.map{|xs|xs.pushx}xss.add[x]pxssend将打印###怎么了?编辑将xs.pushx更改为xs+[x]将修复它。 最佳答案 您实际上是在更改集合中的对象,这是不允许的。来自documentation:Setassumesthattheidentit

随机推荐