学fpga(hls之中断)

在fpga ip设计里面,中断是不可缺少的。一般来说,ip处理结束之后,要么用轮询的方法获得结果,要么用中断的方法获取结果。两种方式都是可以拿来使用,只是一般来说,轮询的方式效率会比较低。今天可以看下,hls里面中断是怎么处理的。不失一般性,可以把之前求平均值的hls代码拿出来分析,

1、hls代码

  1. #include <ap_cint.h>
  2. uint32 _average_int(uint32* array, int num)
  3. {
  4. uint32 sum = 0;
  5. int i;
  6.  
  7. for(i = 0; i < num; i++)
  8. {
  9. sum += array[i];
  10. }
  11.  
  12. return sum / num;
  13. }
  14.  
  15. extern "C" uint32 average_int(uint32* array, int num)
  16. {
  17. #pragma HLS INTERFACE s_axilite port=return
  18. #pragma HLS INTERFACE s_axilite port=num
  19. #pragma HLS INTERFACE m_axi depth=1024 offset=slave port=array
  20.  
  21. uint32 result = _average_int(array, num);
  22. return result;
  23. }

        这段代码只是完成基本功能,大家可以忽略它的性能设计,这部分不做考虑。

2、综合、export

        利用vivado hls软件进行综合和导出。

3、查看生成的驱动代码,

学fpga(hls之中断) - 第1张

        主要的接口都在xaverage_int.h里面。

4、查看xaverage_int.h文件

  1. // ==============================================================
  2. // File generated on Sun May 08 06:30:23 +0800 2022
  3. // Vivado(TM) HLS - High-Level Synthesis from C, C++ and SystemC v2018.3 (64-bit)
  4. // SW Build 2405991 on Thu Dec 6 23:38:27 MST 2018
  5. // IP Build 2404404 on Fri Dec 7 01:43:56 MST 2018
  6. // Copyright 1986-2018 Xilinx, Inc. All Rights Reserved.
  7. // ==============================================================
  8. #ifndef XAVERAGE_INT_H
  9. #define XAVERAGE_INT_H
  10.  
  11. #ifdef __cplusplus
  12. extern "C" {
  13. #endif
  14.  
  15. /***************************** Include Files *********************************/
  16. #ifndef __linux__
  17. #include "xil_types.h"
  18. #include "xil_assert.h"
  19. #include "xstatus.h"
  20. #include "xil_io.h"
  21. #else
  22. #include <stdint.h>
  23. #include <assert.h>
  24. #include <dirent.h>
  25. #include <fcntl.h>
  26. #include <stdio.h>
  27. #include <stdlib.h>
  28. #include <string.h>
  29. #include <sys/mman.h>
  30. #include <unistd.h>
  31. #include <stddef.h>
  32. #endif
  33. #include "xaverage_int_hw.h"
  34.  
  35. /**************************** Type Definitions ******************************/
  36. #ifdef __linux__
  37. typedef uint8_t u8;
  38. typedef uint16_t u16;
  39. typedef uint32_t u32;
  40. #else
  41. typedef struct {
  42. u16 DeviceId;
  43. u32 Axilites_BaseAddress;
  44. } XAverage_int_Config;
  45. #endif
  46.  
  47. typedef struct {
  48. u32 Axilites_BaseAddress;
  49. u32 IsReady;
  50. } XAverage_int;
  51.  
  52. /***************** Macros (Inline Functions) Definitions *********************/
  53. #ifndef __linux__
  54. #define XAverage_int_WriteReg(BaseAddress, RegOffset, Data) \
  55. Xil_Out32((BaseAddress) + (RegOffset), (u32)(Data))
  56. #define XAverage_int_ReadReg(BaseAddress, RegOffset) \
  57. Xil_In32((BaseAddress) + (RegOffset))
  58. #else
  59. #define XAverage_int_WriteReg(BaseAddress, RegOffset, Data) \
  60. *(volatile u32*)((BaseAddress) + (RegOffset)) = (u32)(Data)
  61. #define XAverage_int_ReadReg(BaseAddress, RegOffset) \
  62. *(volatile u32*)((BaseAddress) + (RegOffset))
  63.  
  64. #define Xil_AssertVoid(expr) assert(expr)
  65. #define Xil_AssertNonvoid(expr) assert(expr)
  66.  
  67. #define XST_SUCCESS 0
  68. #define XST_DEVICE_NOT_FOUND 2
  69. #define XST_OPEN_DEVICE_FAILED 3
  70. #define XIL_COMPONENT_IS_READY 1
  71. #endif
  72.  
  73. /************************** Function Prototypes *****************************/
  74. #ifndef __linux__
  75. int XAverage_int_Initialize(XAverage_int *InstancePtr, u16 DeviceId);
  76. XAverage_int_Config* XAverage_int_LookupConfig(u16 DeviceId);
  77. int XAverage_int_CfgInitialize(XAverage_int *InstancePtr, XAverage_int_Config *ConfigPtr);
  78. #else
  79. int XAverage_int_Initialize(XAverage_int *InstancePtr, const char* InstanceName);
  80. int XAverage_int_Release(XAverage_int *InstancePtr);
  81. #endif
  82.  
  83. void XAverage_int_Start(XAverage_int *InstancePtr);
  84. u32 XAverage_int_IsDone(XAverage_int *InstancePtr);
  85. u32 XAverage_int_IsIdle(XAverage_int *InstancePtr);
  86. u32 XAverage_int_IsReady(XAverage_int *InstancePtr);
  87. void XAverage_int_EnableAutoRestart(XAverage_int *InstancePtr);
  88. void XAverage_int_DisableAutoRestart(XAverage_int *InstancePtr);
  89. u32 XAverage_int_Get_return(XAverage_int *InstancePtr);
  90.  
  91. void XAverage_int_Set_array_r(XAverage_int *InstancePtr, u32 Data);
  92. u32 XAverage_int_Get_array_r(XAverage_int *InstancePtr);
  93. void XAverage_int_Set_num(XAverage_int *InstancePtr, u32 Data);
  94. u32 XAverage_int_Get_num(XAverage_int *InstancePtr);
  95.  
  96. void XAverage_int_InterruptGlobalEnable(XAverage_int *InstancePtr);
  97. void XAverage_int_InterruptGlobalDisable(XAverage_int *InstancePtr);
  98. void XAverage_int_InterruptEnable(XAverage_int *InstancePtr, u32 Mask);
  99. void XAverage_int_InterruptDisable(XAverage_int *InstancePtr, u32 Mask);
  100. void XAverage_int_InterruptClear(XAverage_int *InstancePtr, u32 Mask);
  101. u32 XAverage_int_InterruptGetEnabled(XAverage_int *InstancePtr);
  102. u32 XAverage_int_InterruptGetStatus(XAverage_int *InstancePtr);
  103.  
  104. #ifdef __cplusplus
  105. }
  106. #endif
  107.  
  108. #endif

5、分析xaverage_int.h文件

        主要的驱动接口分成这么几个部分,

        初始化函数,XAverage_int_Initialize等

        状态检查函数,XAverage_int_Start、XAverage_int_IsDone等

        获取返回值函数,XAverage_int_Get_return

        参数设置函数,XAverage_int_Set_array_r、XAverage_int_Set_num等

        中断处理函数,XAverage_int_InterruptEnable、XAverage_int_InterruptClear等

6、关于中断和查询

        在5中提到的中断函数都可以使用。其实如果不需要中断,仅仅利用状态检查函数,也是可以获取计算结果的,这里面的取舍取决于具体的应用场景。

7、寄存器的布局

        关于寄存器的相关信息,主要来自于xaverage_int_hw.h文件,

  1. // ==============================================================
  2. // File generated on Sun May 08 06:30:23 +0800 2022
  3. // Vivado(TM) HLS - High-Level Synthesis from C, C++ and SystemC v2018.3 (64-bit)
  4. // SW Build 2405991 on Thu Dec 6 23:38:27 MST 2018
  5. // IP Build 2404404 on Fri Dec 7 01:43:56 MST 2018
  6. // Copyright 1986-2018 Xilinx, Inc. All Rights Reserved.
  7. // ==============================================================
  8. // AXILiteS
  9. // 0x00 : Control signals
  10. // bit 0 - ap_start (Read/Write/COH)
  11. // bit 1 - ap_done (Read/COR)
  12. // bit 2 - ap_idle (Read)
  13. // bit 3 - ap_ready (Read)
  14. // bit 7 - auto_restart (Read/Write)
  15. // others - reserved
  16. // 0x04 : Global Interrupt Enable Register
  17. // bit 0 - Global Interrupt Enable (Read/Write)
  18. // others - reserved
  19. // 0x08 : IP Interrupt Enable Register (Read/Write)
  20. // bit 0 - Channel 0 (ap_done)
  21. // bit 1 - Channel 1 (ap_ready)
  22. // others - reserved
  23. // 0x0c : IP Interrupt Status Register (Read/TOW)
  24. // bit 0 - Channel 0 (ap_done)
  25. // bit 1 - Channel 1 (ap_ready)
  26. // others - reserved
  27. // 0x10 : Data signal of ap_return
  28. // bit 31~0 - ap_return[31:0] (Read)
  29. // 0x18 : Data signal of array_r
  30. // bit 31~0 - array_r[31:0] (Read/Write)
  31. // 0x1c : reserved
  32. // 0x20 : Data signal of num
  33. // bit 31~0 - num[31:0] (Read/Write)
  34. // 0x24 : reserved
  35. // (SC = Self Clear, COR = Clear on Read, TOW = Toggle on Write, COH = Clear on Handshake)
  36.  
  37. #define XAVERAGE_INT_AXILITES_ADDR_AP_CTRL 0x00
  38. #define XAVERAGE_INT_AXILITES_ADDR_GIE 0x04
  39. #define XAVERAGE_INT_AXILITES_ADDR_IER 0x08
  40. #define XAVERAGE_INT_AXILITES_ADDR_ISR 0x0c
  41. #define XAVERAGE_INT_AXILITES_ADDR_AP_RETURN 0x10
  42. #define XAVERAGE_INT_AXILITES_BITS_AP_RETURN 32
  43. #define XAVERAGE_INT_AXILITES_ADDR_ARRAY_R_DATA 0x18
  44. #define XAVERAGE_INT_AXILITES_BITS_ARRAY_R_DATA 32
  45. #define XAVERAGE_INT_AXILITES_ADDR_NUM_DATA 0x20
  46. #define XAVERAGE_INT_AXILITES_BITS_NUM_DATA 32

8、ip、驱动和中断

        利用fpga设计好ip,这只是第一步。后面还需要移植好驱动函数,如果是裸机系统可能不需要手动移植驱动代码了,当os变成linux的时候,还需要转成kernel driver。当然,变成kernel driver之后,后面就是具体的调用了。这中间,ip如果有中断,还需要把中断反馈到zynq cpu上面。

本文原创,作者:二牛学FPGA,其版权均为FPGA线上课程平台|最全栈的FPGA学习平台|FPGA工程师认证培训所有。
如需转载,请注明出处:https://z.shaonianxue.cn/9563.html

"愿我的文字能带给您一丝美好"

还没有人赞赏,支持一下

评论

A 为本文作者,G 为游客总数:0
加载中…

提交评论

游客,您好,欢迎参与讨论。

我的购物车

购物车为空

优惠券

没有优惠券