您的位置:首页 > 其它

HLS_ug871笔记

2016-07-23 14:18 369 查看
July 23, 2016

作者:dengshuai_super

出处:http://blog.csdn.net/dengshuai_super/article/details/52004095

声明:转载请注明作者及出处。

来源:

Chapter 10:Using HLS IP in a Zynq AP Soc Design

Lab 1: Implement Vivado HLS IP on a Zynq Device

这个实验练习集成了HLS IP 和(被HLS创建用来控制“实现在Zynq设备上的”设计的IP的)软件驱动程序。

Step 4:Creating an IP Integrator Block Design of the System

(1)Create Block Design

(2)Add IP(ZYNQ7 Processing System)

(3)双击IP,Presets—>选择板子型号

(4)MIO Configuration—> Application Processor Unit—->取消对Timer 0的选择(被选择的定时器都被取消)

(5)Interrupts—->Fabric Interrupts—->选择IRQ_F2P[15:0]—->OK

(6)单击Run Block Automation—>确认processing_system7_0被选择—->确认Apply Board Presets没被选择(如果选择了,它将重新应用我们第4步取消的定时器,造成Zynq设计块中有额外的端口)

(7)Add HLS IP

(8)单击Run Connection Automation(自动连线)

(9)选择S_AXI_HLS_MACC_PERIPH_BUS—>单击OK

(10)连接hls_macc_0的中断引脚interrupt(光标变成铅笔形状) 到PS7(processing_system7_0)上的IRQ_F2P[0:0]端口。

(11)选择Address Editor选项卡,确认hls_macc_0周围都有一个主地址范围。如果没有,点击Auto Assign Address。

(12)单击Validate Design图标,验证设计。

(13)在成功验证后,保存块设计。

Step 5: Implementing the System

在进行系统设计之前,你必须生成执行源(implementation sources)并创建一个HDL包装器作为合成和实现的顶层模块。

(1)返回到Project Manager窗口。

(2)右键Design Sources下的Zynq_Design(.bd对象)—>Generate Output Products

(3)Generate

(4)右键Design Sources下的Zynq_Design(.bd对象)—>Create HDL Wrapper—>OK

设计源文件树的顶层变为Zynq_Design_wrapper.v 文件。设计现在准备被综合,实现并且生成一个FPGA 编程比特流(FPGA progamming bitstream)。

(5)点击Generate Bitstream —> Yes

(6)Open Implemented Design —->OK

Step 6 : Developing Software and Running it on the ZYNQ System

你现在准备导出设计到Xilinux SDK。在SDK ,你创建运行在ZC702板子(如果有)上的软件。在HLS 导出Vivado IP Catalog package的期间生成这个HLS 块的驱动。为了让PS7软件可以和这个块通信,在SDK中必须提供这个驱动

(1)Vivado File menu 选择Export—>Export Hardward

(2)保证Include Bitstream 这个选项被选—>点击OK。

(3)Vivado File menu 选择Launch SDK。

(4)OK

(5)SDK 选择File–>New—>Application Project—>name:Zynq_Design_Test—>Next—>Hello World—>Finish

(6)给ZC702上电,并且测试这个HelloWolld程序,确保板子所有的连接允许你往FPGA设备上下载比特流。

(7)单击Xilinx Tools—>Program FPGA(or toolrar icon)

(8)Setup a Terminal in the Tab at bottom of workspace。(底部工具栏挨着Console,叫Terminal 1)

点击Connect图标—->选择Connection Type —>Serial—>选择USB串口线连接的端口(windows上可以打开设备管理器查看)—>波特率改为115200—>OK(也可以在右键应用程序项目Zynq_Design_Test—>Run as—>Run Configurations设置)

(9)在浏览窗格,右键应用程序项目Zynq_Design_Test—>Run as—>Launch on Hardware—>切换到Terminal标签—>确认Hello World接收到了。

Step 7 : Modify software to communicate with HLS block

这个完全修改好的源文件在教程文件的arm_code目录中。(将HelloWorld.c改为下面)

#include <stdio.h>
#include "platform.h"
// Add BSP header files
#include <stdlib.h>  // Standard C functions, e.g. exit()
#include <stdbool.h> // Provides a Boolean data type for ANSI/ISO-C
#include "xparameters.h
cff2
" // Parameter definitions for processor periperals
#include "xscugic.h"     // Processor interrupt controller device driver
#include "XHls_macc.h"   // Device driver for HLS HW block

// HLS macc HW instance
XHls_macc HlsMacc;
//Interrupt Controller Instance
XScuGic ScuGic;
// Global variable definitions - used by ISR
volatile static int RunHlsMacc = 0;
volatile static int ResultAvailHlsMacc = 0;

// Setup and helper functions
int setup_interrupt();
int hls_macc_init(XHls_macc *hls_maccPtr);
void hls_macc_start(void *InstancePtr);
// The ISR prototype
void hls_macc_isr(void *InstancePtr);
// Software model of HLS hardware
void sw_macc(int a, int b, int *accum, bool accum_clr);

int main()
{
print("Program to test communication with HLS MACC block in PL\n\r");
int a = 2, b = 21;
int res_hw;
int res_sw;
int i;
int status;

//Setup the matrix mult
status = hls_macc_init(&HlsMacc);
if(status != XST_SUCCESS){
print("HLS peripheral setup failed\n\r");
exit(-1);
}
//Setup the interrupt
status = setup_interrupt();
if(status != XST_SUCCESS){
print("Interrupt setup failed\n\r");
exit(-1);
}

//set the input parameters of the HLS block
XHls_macc_SetA(&HlsMacc, a);
XHls_macc_SetB(&HlsMacc, b);
XHls_macc_SetAccum_clr(&HlsMacc, 1);

if (XHls_macc_IsReady(&HlsMacc))
print("HLS peripheral is ready.  Starting... ");
else {
print("!!! HLS peripheral is not ready! Exiting...\n\r");
exit(-1);
}

if (0) { // use interrupt
hls_macc_start(&HlsMacc);
while(!ResultAvailHlsMacc)
; // spin
res_hw = XHls_macc_GetAccum(&HlsMacc);
print("Interrupt received from HLS HW.\n\r");
} else { // Simple non-interrupt driven test
XHls_macc_Start(&HlsMacc);
do {
res_hw = XHls_macc_GetAccum(&HlsMacc);
} while (!XHls_macc_IsReady(&HlsMacc));
print("Detected HLS peripheral complete. Result received.\n\r");
}

//call the software version of the function
sw_macc(a, b, &res_sw, false);

printf("Result from HW: %d; Result from SW: %d\n\r", res_hw, res_sw);
if (res_hw == res_sw) {
print("*** Results match ***\n\r");
status = 0;
}
else {
print("!!! MISMATCH !!!\n\r");
status = -1;
}

cleanup_platform();
return status;
}

void sw_macc(int a, int b, int *accum, bool accum_clr)
{
static int accum_reg = 0;
if (accum_clr)
accum_reg = 0;
accum_reg += a * b;
*accum = accum_reg;
}

int hls_macc_init(XHls_macc *hls_maccPtr)
{
XHls_macc_Config *cfgPtr;
int status;

cfgPtr = XHls_macc_LookupConfig(XPAR_XHLS_MACC_0_DEVICE_ID);
if (!cfgPtr) {
print("ERROR: Lookup of acclerator configuration failed.\n\r");
return XST_FAILURE;
}
status = XHls_macc_CfgInitialize(hls_maccPtr, cfgPtr);
if (status != XST_SUCCESS) {
print("ERROR: Could not initialize accelerator.\n\r");
return XST_FAILURE;
}
return status;
}

void hls_macc_start(void *InstancePtr){
XHls_macc *pAccelerator = (XHls_macc *)InstancePtr;
XHls_macc_InterruptEnable(pAccelerator,1);
XHls_macc_InterruptGlobalEnable(pAccelerator);
XHls_macc_Start(pAccelerator);
}

void hls_macc_isr(void *InstancePtr){
XHls_macc *pAccelerator = (XHls_macc *)InstancePtr;

//Disable the global interrupt
XHls_macc_InterruptGlobalDisable(pAccelerator);
//Disable the local interrupt
XHls_macc_InterruptDisable(pAccelerator,0xffffffff);

// clear the local interrupt
XHls_macc_InterruptClear(pAccelerator,1);

ResultAvailHlsMacc = 1;
// restart the core if it should run again
if(RunHlsMacc){
hls_macc_start(pAccelerator);
}
}

int setup_interrupt()
{
//This functions sets up the interrupt on the ARM
int result;
XScuGic_Config *pCfg = XScuGic_LookupConfig(XPAR_SCUGIC_SINGLE_DEVICE_ID);
if (pCfg == NULL){
print("Interrupt Configuration Lookup Failed\n\r");
return XST_FAILURE;
}
result = XScuGic_CfgInitialize(&ScuGic,pCfg,pCfg->CpuBaseAddress);
if(result != XST_SUCCESS){
return result;
}
// self test
result = XScuGic_SelfTest(&ScuGic);
if(result != XST_SUCCESS){
return result;
}
// Initialize the exception handler
Xil_ExceptionInit();
// Register the exception handler
//print("Register the exception handler\n\r");
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,(Xil_ExceptionHandler)XScuGic_InterruptHandler,&ScuGic);
//Enable the exception handler
Xil_ExceptionEnable();
// Connect the Adder ISR to the exception table
//print("Connect the Adder ISR to the Exception handler table\n\r");
result = XScuGic_Connect(&ScuGic,XPAR_FABRIC_HLS_MACC_0_INTERRUPT_INTR,(Xil_InterruptHandler)hls_macc_isr,&HlsMacc);
if(result != XST_SUCCESS){
return result;
}
//print("Enable the Adder ISR\n\r");
XScuGic_Enable(&ScuGic,XPAR_FABRIC_HLS_MACC_0_INTERRUPT_INTR);
return XST_SUCCESS;
}


Lab 2 : Streaming Data Between the Zynq CPU and HLS Accelerator Blocks

该实验演示了一种常见的高性能连接方案,用于连接(以流的方式消耗来源于CPU内存数据或者产生以CPU内存为目的地的数据的)硬件加速器模块。

本教程使用和“Using HLS IP in IP Intergrator”Lab1中相同的HLS和XFFT IP模块。在这个实验中,这些模块通过AXI DMA IP Core 连接到Zynq7 Processing System上的HP0 Slave AXI4 port。

硬件加速器模块是自由运行的,不需要驱动程序;只要数据被推进CPU或者从CPU被推出(通常简单的称为处理系统或者PS)。

这个实验强调软件需要避免高速缓存一致性问题。(avoid cache coherency issues)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: