学fpga(hls之中断)

二牛学FPGA
文章2025-07-18
375

在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入门FPGA工程fpga教程HLSxilinx
浏览 375
分享:

相关推荐

同频道 · 相近分类

暂无相关推荐

作者

二牛学FPGA查看主页

同分类阅读

文章

延伸阅读与实操

  • 文章 + 课程联动深度文章常对应体系课章节,可一键选课。
  • 学习产出可参考笔记与作业案例在学习产出广场持续更新。

探索全站