学fpga(hls之中断)
在fpga ip设计里面,中断是不可缺少的。一般来说,ip处理结束之后,要么用轮询的方法获得结果,要么用中断的方法获取结果。两种方式都是可以拿来使用,只是一般来说,轮询的方式效率会比较低。今天可以看下,hls里面中断是怎么处理的。不失一般性,可以把之前求平均值的hls代码拿出来分析,
1、hls代码
- #include <ap_cint.h>
- uint32 _average_int(uint32* array, int num)
- {
- uint32 sum = 0;
- int i;
- for(i = 0; i < num; i++)
- {
- sum += array[i];
- }
- return sum / num;
- }
- extern "C" uint32 average_int(uint32* array, int num)
- {
- #pragma HLS INTERFACE s_axilite port=return
- #pragma HLS INTERFACE s_axilite port=num
- #pragma HLS INTERFACE m_axi depth=1024 offset=slave port=array
- uint32 result = _average_int(array, num);
- return result;
- }
这段代码只是完成基本功能,大家可以忽略它的性能设计,这部分不做考虑。
2、综合、export
利用vivado hls软件进行综合和导出。
3、查看生成的驱动代码,

主要的接口都在xaverage_int.h里面。
4、查看xaverage_int.h文件
- // ==============================================================
- // File generated on Sun May 08 06:30:23 +0800 2022
- // Vivado(TM) HLS - High-Level Synthesis from C, C++ and SystemC v2018.3 (64-bit)
- // SW Build 2405991 on Thu Dec 6 23:38:27 MST 2018
- // IP Build 2404404 on Fri Dec 7 01:43:56 MST 2018
- // Copyright 1986-2018 Xilinx, Inc. All Rights Reserved.
- // ==============================================================
- #ifndef XAVERAGE_INT_H
- #define XAVERAGE_INT_H
- #ifdef __cplusplus
- extern "C" {
- #endif
- /***************************** Include Files *********************************/
- #ifndef __linux__
- #include "xil_types.h"
- #include "xil_assert.h"
- #include "xstatus.h"
- #include "xil_io.h"
- #else
- #include <stdint.h>
- #include <assert.h>
- #include <dirent.h>
- #include <fcntl.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <sys/mman.h>
- #include <unistd.h>
- #include <stddef.h>
- #endif
- #include "xaverage_int_hw.h"
- /**************************** Type Definitions ******************************/
- #ifdef __linux__
- typedef uint8_t u8;
- typedef uint16_t u16;
- typedef uint32_t u32;
- #else
- typedef struct {
- u16 DeviceId;
- u32 Axilites_BaseAddress;
- } XAverage_int_Config;
- #endif
- typedef struct {
- u32 Axilites_BaseAddress;
- u32 IsReady;
- } XAverage_int;
- /***************** Macros (Inline Functions) Definitions *********************/
- #ifndef __linux__
- #define XAverage_int_WriteReg(BaseAddress, RegOffset, Data) \
- Xil_Out32((BaseAddress) + (RegOffset), (u32)(Data))
- #define XAverage_int_ReadReg(BaseAddress, RegOffset) \
- Xil_In32((BaseAddress) + (RegOffset))
- #else
- #define XAverage_int_WriteReg(BaseAddress, RegOffset, Data) \
- *(volatile u32*)((BaseAddress) + (RegOffset)) = (u32)(Data)
- #define XAverage_int_ReadReg(BaseAddress, RegOffset) \
- *(volatile u32*)((BaseAddress) + (RegOffset))
- #define Xil_AssertVoid(expr) assert(expr)
- #define Xil_AssertNonvoid(expr) assert(expr)
- #define XST_SUCCESS 0
- #define XST_DEVICE_NOT_FOUND 2
- #define XST_OPEN_DEVICE_FAILED 3
- #define XIL_COMPONENT_IS_READY 1
- #endif
- /************************** Function Prototypes *****************************/
- #ifndef __linux__
- int XAverage_int_Initialize(XAverage_int *InstancePtr, u16 DeviceId);
- XAverage_int_Config* XAverage_int_LookupConfig(u16 DeviceId);
- int XAverage_int_CfgInitialize(XAverage_int *InstancePtr, XAverage_int_Config *ConfigPtr);
- #else
- int XAverage_int_Initialize(XAverage_int *InstancePtr, const char* InstanceName);
- int XAverage_int_Release(XAverage_int *InstancePtr);
- #endif
- void XAverage_int_Start(XAverage_int *InstancePtr);
- u32 XAverage_int_IsDone(XAverage_int *InstancePtr);
- u32 XAverage_int_IsIdle(XAverage_int *InstancePtr);
- u32 XAverage_int_IsReady(XAverage_int *InstancePtr);
- void XAverage_int_EnableAutoRestart(XAverage_int *InstancePtr);
- void XAverage_int_DisableAutoRestart(XAverage_int *InstancePtr);
- u32 XAverage_int_Get_return(XAverage_int *InstancePtr);
- void XAverage_int_Set_array_r(XAverage_int *InstancePtr, u32 Data);
- u32 XAverage_int_Get_array_r(XAverage_int *InstancePtr);
- void XAverage_int_Set_num(XAverage_int *InstancePtr, u32 Data);
- u32 XAverage_int_Get_num(XAverage_int *InstancePtr);
- void XAverage_int_InterruptGlobalEnable(XAverage_int *InstancePtr);
- void XAverage_int_InterruptGlobalDisable(XAverage_int *InstancePtr);
- void XAverage_int_InterruptEnable(XAverage_int *InstancePtr, u32 Mask);
- void XAverage_int_InterruptDisable(XAverage_int *InstancePtr, u32 Mask);
- void XAverage_int_InterruptClear(XAverage_int *InstancePtr, u32 Mask);
- u32 XAverage_int_InterruptGetEnabled(XAverage_int *InstancePtr);
- u32 XAverage_int_InterruptGetStatus(XAverage_int *InstancePtr);
- #ifdef __cplusplus
- }
- #endif
- #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文件,
- // ==============================================================
- // File generated on Sun May 08 06:30:23 +0800 2022
- // Vivado(TM) HLS - High-Level Synthesis from C, C++ and SystemC v2018.3 (64-bit)
- // SW Build 2405991 on Thu Dec 6 23:38:27 MST 2018
- // IP Build 2404404 on Fri Dec 7 01:43:56 MST 2018
- // Copyright 1986-2018 Xilinx, Inc. All Rights Reserved.
- // ==============================================================
- // AXILiteS
- // 0x00 : Control signals
- // bit 0 - ap_start (Read/Write/COH)
- // bit 1 - ap_done (Read/COR)
- // bit 2 - ap_idle (Read)
- // bit 3 - ap_ready (Read)
- // bit 7 - auto_restart (Read/Write)
- // others - reserved
- // 0x04 : Global Interrupt Enable Register
- // bit 0 - Global Interrupt Enable (Read/Write)
- // others - reserved
- // 0x08 : IP Interrupt Enable Register (Read/Write)
- // bit 0 - Channel 0 (ap_done)
- // bit 1 - Channel 1 (ap_ready)
- // others - reserved
- // 0x0c : IP Interrupt Status Register (Read/TOW)
- // bit 0 - Channel 0 (ap_done)
- // bit 1 - Channel 1 (ap_ready)
- // others - reserved
- // 0x10 : Data signal of ap_return
- // bit 31~0 - ap_return[31:0] (Read)
- // 0x18 : Data signal of array_r
- // bit 31~0 - array_r[31:0] (Read/Write)
- // 0x1c : reserved
- // 0x20 : Data signal of num
- // bit 31~0 - num[31:0] (Read/Write)
- // 0x24 : reserved
- // (SC = Self Clear, COR = Clear on Read, TOW = Toggle on Write, COH = Clear on Handshake)
- #define XAVERAGE_INT_AXILITES_ADDR_AP_CTRL 0x00
- #define XAVERAGE_INT_AXILITES_ADDR_GIE 0x04
- #define XAVERAGE_INT_AXILITES_ADDR_IER 0x08
- #define XAVERAGE_INT_AXILITES_ADDR_ISR 0x0c
- #define XAVERAGE_INT_AXILITES_ADDR_AP_RETURN 0x10
- #define XAVERAGE_INT_AXILITES_BITS_AP_RETURN 32
- #define XAVERAGE_INT_AXILITES_ADDR_ARRAY_R_DATA 0x18
- #define XAVERAGE_INT_AXILITES_BITS_ARRAY_R_DATA 32
- #define XAVERAGE_INT_AXILITES_ADDR_NUM_DATA 0x20
- #define XAVERAGE_INT_AXILITES_BITS_NUM_DATA 32
8、ip、驱动和中断
利用fpga设计好ip,这只是第一步。后面还需要移植好驱动函数,如果是裸机系统可能不需要手动移植驱动代码了,当os变成linux的时候,还需要转成kernel driver。当然,变成kernel driver之后,后面就是具体的调用了。这中间,ip如果有中断,还需要把中断反馈到zynq cpu上面。
"愿我的文字能带给您一丝美好"
分享海报

学fpga(hls之中断)
在fpgaip设计里面,中断是不可缺少的。一般来说,ip处理结束之后,要么用轮询的方法获得结果,要…
FPGA线上课程平台|最全栈的FPGA学习平台|FPGA工程师认证培训
FPGA在线学习平台
评论
A 为本文作者,G 为游客总数:0