[X]关闭

[米联客-XILINX-H3_CZ08_7100] FPGA_SDK高级篇连载-18DAQ9767-PS 波形数据共享给 PL

文档创建者:FPGA课程
浏览次数:186
最后更新:2024-10-10
文档课程分类-AMD-ZYNQ
AMD-ZYNQ: ZYNQ-SOC » 1_SDK应用方案(仅旗舰型号) » 2-SDK高级应用方案
本帖最后由 FPGA课程 于 2024-10-10 18:19 编辑

​ 软件版本:VIVADO2021.1
操作系统:WIN10 64bit
硬件平台:适用 XILINX A7/K7/Z7/ZU/KU 系列 FPGA
实验平台:米联客-MLK-H3-CZ08-7100开发板
板卡获取平台:https://milianke.tmall.com/
登录“米联客”FPGA社区 http://www.uisrc.com 视频课程、答疑解惑!



1概述
DAQ9767是一款2通道14bit 125M高精度 DAC数模转换模块。在前面的方案中,主要都是讲解PL数据如何共享给PS,本方案的目标在于演示如何把PS部分的数据写到PS DDR后,共享给PL。
本文通过PS写测试波形到内中,包括锯齿波、三角波、方波,然后通知PL的uifdma_dbuf读取内存中的测试数据,驱动DAQ005输出 DAC模块输出波形。
实验目的:
1:掌握uifdmadbuf配置成非视频模式的情况下的参数设置
2:掌握PS DDR数据如何通过uifdmadbuf读出并驱动DAC模块输出波形
2系统框图
以下方案中,PS先把波形数据写入DDR中,然后通过控制AXI-GPIO控制缓存的切换。我们这里一共需要显示3种波形,分别是锯齿波、三角波、方波,每种波形每间隔2S切换一次。
af7dbdff944c43b493b3341ff0533c1f.jpg
3硬件电路分析
硬件接口和子卡模块请阅读“附录1”
配套工程的FPGA PIN脚定义路径为soc_prj/uisrc/04_pin/ fpga_pin.xdc。
4搭建SOC系统工程
4.1PL图形化编程
15db057a698e4230a44a9288b4098601.jpg
1:uifdma_dbuf设置
本方案中,我们升级了uifdma_dbuf,给写通道增加了ud_wfull信号,以及读通道增加了ud_empty信号。这样可以确保读出数据的时候都是有效数据。
为了显示3种波形,我们设置3帧缓存。WBaseaddr缓存的基地址只要设置合适的值即可,这里设置0x10000000 = 256MB,这样保留了低256MB给应用程序使用。
WDsizebits设置每个缓存的大小,2^20次方=1MBYTE。
所以下面的参数XSize*YSize*W_Datawidth/8=256KB.其中已知W_Datawidth=32,所以只要正确设置XSize和YSize。通常来说设置越大的XSize传输效率也高,但是需要消耗的资源也会更多。我们这里设置XSize=2048,Ysize设置32。这样对于DAQ967X 2通道,每个通道具有2048*32= 65536个波形点。对于14bit DAC,可以绘制65536/2^14=4个周期的波形。
在SDK中定义如下地址:
#define BUF_BASE_SIZE    0x10000000
#define BUF_RANG_SIZE   0x100000
#define BUF1_ADDR BUF_BASE_SIZE + BUF_RANG_SIZE*0;
#define BUF2_ADDR BUF_BASE_SIZE + BUF_RANG_SIZE*1;
#define BUF3_ADDR BUF_BASE_SIZE + BUF_RANG_SIZE*2;
2eb2fa888881430eb599c9b6f4190877.jpg
2:uiFDMA设置
Fdma的数据位宽可以设置128这样效率最高。
d3ac2b49ccf246dd9dcb7c42d4c608ff.jpg
3:AXI Interconnect设置
设置FIFO可以增加数据的吞吐能力
4a5ff06afa4f4b2da497fc97e60ddde9.jpg
4:修改system_wrapper.v
将自动产生的system_wrapper.v复制到本方案工程路径soc_prj/uisrc/01_rtl/system_wrapper.v并对其修改,修改好的代码如下:
  1. /*******************************MILIANKE*******************************
  2. *Company : MiLianKe Electronic Technology Co., Ltd.
  3. *WebSite:https://www.milianke.com
  4. *TechWeb:https://www.uisrc.com
  5. *tmall-shop:https://milianke.tmall.com
  6. *jd-shop:https://milianke.jd.com
  7. *taobao-shop1: https://milianke.taobao.com
  8. *Create Date: 2021/10/15
  9. *Module Name:system_wrapper
  10. *File Name:system_wrapper.v
  11. *Description:
  12. *The reference demo provided by Milianke is only used for learning.
  13. *We cannot ensure that the demo itself is free of bugs, so users
  14. *should be responsible for the technical problems and consequences
  15. *caused by the use of their own products.
  16. *Copyright: Copyright (c) MiLianKe
  17. *All rights reserved.
  18. *Revision: 1.0
  19. *Signal description
  20. *1) _i input
  21. *2) _o output
  22. *3) _n activ low
  23. *4) _dg debug signal
  24. *5) _r delay or register
  25. *6) _s state mechine
  26. *********************************************************************/
  27. `timescale 1 ps / 1 ps
  28. module system_wrapper
  29. (
  30. inout wire [14:0]DDR_addr,
  31. inout wire [2:0]DDR_ba,
  32. inout wire DDR_cas_n,
  33. inout wire DDR_ck_n,
  34. inout wire DDR_ck_p,
  35. inout wire DDR_cke,
  36. inout wire DDR_cs_n,
  37. inout wire [3:0]DDR_dm,
  38. inout wire [31:0]DDR_dq,
  39. inout wire [3:0]DDR_dqs_n,
  40. inout wire [3:0]DDR_dqs_p,
  41. inout wire DDR_odt,
  42. inout wire DDR_ras_n,
  43. inout wire DDR_reset_n,
  44. inout wire DDR_we_n,
  45. inout wire FIXED_IO_ddr_vrn,
  46. inout wire FIXED_IO_ddr_vrp,
  47. inout wire [53:0]FIXED_IO_mio,
  48. inout wire FIXED_IO_ps_clk,
  49. inout wire FIXED_IO_ps_porb,
  50. inout wire FIXED_IO_ps_srstb,
  51. //******************************
  52. output wire         card_power_en,
  53. output wire  [13:0] ad9767_DB_A,
  54. output wire         ad9767_WRT_A,
  55. output wire         ad9767_clk_A,
  56. output wire  [13:0] ad9767_DB_B,
  57. output wire         ad9767_WRT_B,
  58. output wire         ad9767_clk_B
  59. );
  60. assign card_power_en = 1'b1;
  61. wire pl_clk;
  62. wire user_rstn;
  63. wire user_start;
  64. wire ud_rde_0;
  65. wire ud_rempty_0;
  66. wire [31:0]ud_rdata_0;
  67. assign ud_rde_0 = (ud_rempty_0==1'b0)&user_start; //读使能信号
  68. assign ad9767_WRT_A = pl_clk;
  69. assign ad9767_clk_A = pl_clk;
  70. assign ad9767_WRT_B = pl_clk;
  71. assign ad9767_clk_B = pl_clk;
  72. assign ad9767_DB_A = ud_rdata_0[13:0];
  73. assign ad9767_DB_B = ud_rdata_0[29:16];
  74. ila_0 ila0_dg
  75. (
  76. .clk(pl_clk),
  77. .probe0({ad9767_DB_A,ad9767_DB_B,ud_rempty_0,user_start})
  78. );
  79. system system_i
  80. (
  81. .DDR_addr(DDR_addr),
  82. .DDR_ba(DDR_ba),
  83. .DDR_cas_n(DDR_cas_n),
  84. .DDR_ck_n(DDR_ck_n),
  85. .DDR_ck_p(DDR_ck_p),
  86. .DDR_cke(DDR_cke),
  87. .DDR_cs_n(DDR_cs_n),
  88. .DDR_dm(DDR_dm),
  89. .DDR_dq(DDR_dq),
  90. .DDR_dqs_n(DDR_dqs_n),
  91. .DDR_dqs_p(DDR_dqs_p),
  92. .DDR_odt(DDR_odt),
  93. .DDR_ras_n(DDR_ras_n),
  94. .DDR_reset_n(DDR_reset_n),
  95. .DDR_we_n(DDR_we_n),
  96. .FIXED_IO_ddr_vrn(FIXED_IO_ddr_vrn),
  97. .FIXED_IO_ddr_vrp(FIXED_IO_ddr_vrp),
  98. .FIXED_IO_mio(FIXED_IO_mio),
  99. .FIXED_IO_ps_clk(FIXED_IO_ps_clk),
  100. .FIXED_IO_ps_porb(FIXED_IO_ps_porb),
  101. .FIXED_IO_ps_srstb(FIXED_IO_ps_srstb),
  102. .pl_clk(pl_clk),
  103. .ud_rdata_0(ud_rdata_0),
  104. .ud_rempty_0(ud_rempty_0),
  105. .ud_rde_0(ud_rde_0),
  106. .user_rstn(user_rstn),
  107. .user_start(user_start)
  108. );
  109. endmodule
复制代码

4.2设置地址分配
de23eb081872487c9457dde2e561fb1f.jpg
4.3添加PIN约束
1:选中PROJECT  MANAGERà Add SourcesàAdd or create constraints,添加XDC约束文件。
8be3590df53c4b34bd9bfb5e3890c219.jpg
2:打开提供例程,复制约束文件中的管脚约束到XDC文件,或者查看原理图,自行添加管脚约束,并保存。
以下是添加配套工程路径下已经提供的pin脚文件。配套工程的pin脚约束文件在uisrc/04_pin路径
4.4编译并导出平台文件
1:单击Block文件à右键àGenerate the Output ProductsàGlobalàGenerate。
2:单击Block文件à右键à Create a HDL wrapper(生成HDL顶层文件)àLet vivado manager wrapper and auto-update(自动更新)。
3:生成Bit文件。
4:导出到硬件: FileàExport HardwareàInclude bitstream
5:导出完成后,对应工程路径的soc_hw路径下有硬件平台文件:system_wrapper.xsa的文件。根据硬件平台文件system_wrapper.xsa来创建需要Platform平台。
072faa6ad2ad49718018d9a49beba0cb.jpg
5搭建Vitis-sdk工程
创建soc_base sdk platform和APP工程的过程不再重复,如果不清楚请参考本章节第一个demo。
5.1创建SDK Platform工程
aff6a4aa81f54bdcaf7fe25efd5a70d6.jpg
5.2创建DAQ9767_fdma_lwip工程
e6d2d47940e14b36a1f21137ef4c0549.jpg
6SDK程序分析
  1. /********************MILIANKE**************************
  2. *Company : MiLianKe Electronic Technology Co., Ltd.
  3. *WebSite:https://www.milianke.com
  4. *TechWeb:https://www.uisrc.com
  5. *tmall-shop:https://milianke.tmall.com
  6. *jd-shop:https://milianke.jd.com
  7. *taobao-shop1: https://milianke.taobao.com
  8. *Create Date: 2021/10/15
  9. *File Name: adc_wave_test.c
  10. *Description: ad7606 and lcdshow wave
  11. *Declaration:
  12. *The reference demo provided by Milianke is only used for learning.
  13. *We cannot ensure that the demo itself is free of bugs, so users
  14. *should be responsible for the technical problems and consequences
  15. *caused by the use of their own products.
  16. *Copyright: Copyright (c) MiLianKe
  17. *All rights reserved.
  18. *Revision: 1.0
  19. ****************************************************/
  20. #include <stdio.h>
  21. #include "math.h"
  22. #include <ctype.h>
  23. #include <stdlib.h>
  24. #include "xil_types.h"
  25. #include "xil_cache.h"
  26. #include "xparameters.h"
  27. #include "sleep.h"
  28. #include "xgpio.h"
  29. //定义数据结构体用于保存DAC数据
  30. typedef struct dac_data_s
  31. {
  32.         u16 dac_a;
  33.         u16 dac_b;
  34. }dac_data_s;
  35. #define BUF_BASE_SIZE   0x10000000
  36. #define BUF_RANG_SIZE          0x100000
  37. #define BUF1_ADDR                BUF_BASE_SIZE + BUF_RANG_SIZE*0;
  38. #define BUF2_ADDR                BUF_BASE_SIZE + BUF_RANG_SIZE*1;
  39. #define BUF3_ADDR                BUF_BASE_SIZE + BUF_RANG_SIZE*2;
  40. dac_data_s *UIFDMA_DBUF[65536] __attribute__ ((__aligned__(32)));
  41. XGpio gpio_user_rstn;
  42. XGpio gpio_user_start;
  43. XGpio uifdma_dbuf_ctr;
  44. //初始化GPIO
  45. void gpio_init(void)
  46. {
  47.         XGpio_Initialize(&gpio_user_rstn, XPAR_GPIO_USER_RSTN_DEVICE_ID);
  48.         XGpio_SetDataDirection(&gpio_user_rstn, 1, 0x0);
  49.         XGpio_DiscreteWrite(&gpio_user_rstn,1,0x0);//set gpio reset=0 reset user logic
  50.         XGpio_Initialize(&gpio_user_start, XPAR_GPIO_USER_START_DEVICE_ID);
  51.         XGpio_SetDataDirection(&gpio_user_start, 1, 0x0);//set gpio user_start=0 stop transmission
  52.         XGpio_Initialize(&uifdma_dbuf_ctr, XPAR_UIFDMA_DBUF_CTR_DEVICE_ID);
  53.         XGpio_SetDataDirection(&uifdma_dbuf_ctr, 1, 0x0);
  54.         XGpio_DiscreteWrite(&uifdma_dbuf_ctr, 1, 0x0);
  55.         XGpio_DiscreteWrite(&gpio_user_rstn,1,0x1);//set gpio reset=1 reset done
  56. }
  57. int main(void)
  58. {
  59.         u32 i,y,rd_buf;
  60.         gpio_init();
  61. //初始化指针的地址
  62.         UIFDMA_DBUF[0] = (void*)BUF1_ADDR;
  63.         UIFDMA_DBUF[1] = (void*)BUF2_ADDR;
  64.         UIFDMA_DBUF[2] = (void*)BUF3_ADDR;
  65. //初始化内存
  66.         memset((u8*)UIFDMA_DBUF[0], 0, 65536*4);//Initialize frame buffers
  67.         memset((u8*)UIFDMA_DBUF[1], 0, 65536*4);//Initialize frame buffers
  68.         memset((u8*)UIFDMA_DBUF[2], 0, 65536*4);//Initialize frame buffers
  69. //初始化内中波形
  70.         for(y=0;y<4;y++)//每个缓存区绘制3段波形
  71.         {
  72.                 for(i=0; i<16384 ; i++)//每个缓冲区绘制波形点数为16384个
  73.                 {
  74. //第一个缓存绘制锯齿波
  75.                         UIFDMA_DBUF[0][i+y*16384].dac_a = i;
  76.                         UIFDMA_DBUF[0][i+y*16384].dac_b = i;
  77. //第二个缓存绘制三角波
  78.                         if(y&1)
  79.                         {
  80.                         UIFDMA_DBUF[1][i+y*16384].dac_a = i;
  81.                         UIFDMA_DBUF[1][i+y*16384].dac_b = i;
  82.                         }
  83.                         else
  84.                         {
  85.                         UIFDMA_DBUF[1][i+y*16384].dac_a = 16383 - i;
  86.                         UIFDMA_DBUF[1][i+y*16384].dac_b = 16383 - i;
  87.                         }
  88. //第三个缓存绘制方波
  89.                         if(i<8192)
  90.                         {
  91.                         UIFDMA_DBUF[2][i+y*16384].dac_a = 16383;
  92.                         UIFDMA_DBUF[2][i+y*16384].dac_b = 16383;
  93.                         }
  94.                         else
  95.                         {
  96.                         UIFDMA_DBUF[2][i+y*16384].dac_a = 0;
  97.                         UIFDMA_DBUF[2][i+y*16384].dac_b = 0;
  98.                         }
  99.                 }
  100.         }
  101. //确保Cache中的数据都能刷入到DDR中
  102.         Xil_DCacheFlushRange((INTPTR)UIFDMA_DBUF[0], 65536*4);
  103.         Xil_DCacheFlushRange((INTPTR)UIFDMA_DBUF[1], 65536*4);
  104.         Xil_DCacheFlushRange((INTPTR)UIFDMA_DBUF[2], 65536*4);
  105. //启动uifdma_dbuf数据读
  106.         XGpio_DiscreteWrite(&gpio_user_start, 1, 0x1);//set gpio user_start=0 stop transmission
  107.         while(1)
  108.         {
  109.             //通过控制GPIO切换帧缓存,循环切换0-1-2每间隔2S
  110.             XGpio_DiscreteWrite(&uifdma_dbuf_ctr, 1, rd_buf%3);
  111.             rd_buf++;
  112.             sleep(2);
  113.         }
  114.         return XST_SUCCESS;
  115. }
复制代码




377549395ab24ea4bbc9b26d5cef97d1.jpg
b4a3b24258734be99c40316d95743fc0.jpg
b63d4de420a24f64bc0b40b6c1ede8f1.jpg
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则