nexys4DDR 實現自定義IP核掛載到axi_4匯流排

ll lllh發表於2020-12-25

nexys4DDR 實現自定義IP核掛載到axi_4匯流排
首先建立一個專案,Creat Block Design ,新增microblaze,並進行如下配置 因為本實驗需要用到中斷,所以配置時新增中斷,microblaze IP配置如圖1所示。
![microblazeIP配置](https://img-blog.csdnimg.cn/20201225153058787.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2xpaHVpMTk5NjUyNA==,size_16,color_FFFFFF,t_70
我的目的為將自定義IP核通過系統的自定義IP,將自己的IP封裝成AXI4 IP。
首先開啟tools-> creat and packege new ip ->creat a new AXI4peripheral,然後給IP核命名,修改IPlocation,改為當前目錄下的 ip_user_files。
在這裡插入圖片描述然後再自己的projec裡查詢剛才建立的IP核 右鍵edit in packager
在這裡插入圖片描述
之後,系統會自動跳轉到 cnn_v1.0 配置的專案。
在這裡插入圖片描述在這裡新增自己需要的輸入輸出埠。由於我之前封裝的IP核埠如下
在這裡插入圖片描述
所以我需要自定義一個輸入,一個輸出,並在模組中新增輸入輸出。
在這裡插入圖片描述
在這裡插入圖片描述
然後開啟頂層檔案下的檔案:
同樣將埠新增進去。由於之前封裝的IP核需要當前定義的AXI4 IP核和microblaze進行通訊,所以,需要兩個暫存器,一個將microblaze傳送的資料寫入暫存器併傳送給自定義IP,另一個暫存器將自定義IP核的結果傳送給microblaze。註釋掉slv_reg0的程式碼, slv_reg0的輸入由自定義IP的輸出給。
在這裡插入圖片描述並在最後給出實現需要功能的程式碼。
在這裡插入圖片描述之後,IP-XACT package IP - cnn。 port and interfaces,可以看到自己新定義的埠,最後review and package-> Re-Package IP.
在這裡插入圖片描述最後,將生成IP核加入到專案中。CNN ip 核如下圖所示:
在這裡插入圖片描述將他和自定義cnn_uart連線,在這裡插入圖片描述為了驗證功能正確性,本文新增七段數碼管和button中斷,最後系統結構如下圖所示
在這裡插入圖片描述之後validate Design,gennerate Output Design, creat HDL wapper,gennerate bitstream,file->Export->Export Hardware,lunch sdk,file->new->application projects,最後,將以下程式碼放入helloworld.c

#include <stdio.h>
#include "platform.h"

#include "xparameters.h"
#include "cnn_axi_mul.h"
#include "xil_io.h"
#include <stdlib.h>
#include "xstatus.h"
#include "xintc.h"
#include "xil_exception.h"
#include "xil_printf.h"
#include "xbasic_types.h"
#include "xgpio.h"

XGpio input;
XGpio output1;
XGpio output2;
//XGpio output1;
#define  CNN_AXI_BASEADDR    XPAR_CNN_AXI_MUL_0_S00_AXI_BASEADDR  //LED IP基地址
#define  CNN_AXI_REG0        CNN_AXI_MUL_S00_AXI_SLV_REG0_OFFSET  //LED IP暫存器地址0
#define  CNN_AXI_REG1        CNN_AXI_MUL_S00_AXI_SLV_REG1_OFFSET  //LED IP暫存器地址1
//#define CNN_BASEADDR	0x43C00000
#define INTC_DEVICE_ID		XPAR_INTC_0_INTC_TYPE
#define INTC_DEVICE_INT_ID    XPAR_MICROBLAZE_0_AXI_INTC_BUTTON_IP2INTC_IRPT_INTR
#define	BTN_INT	   XGPIO_IR_CH1_MASK
void DeviceDriverHandler(void *CallbackRef);

static  XIntc InterruptController;
volatile static int InterruptProcessed = FALSE;

void delay(u32 ms)
{
	 volatile u32 Delay1=0;
	 volatile u32 Delay2=0;

	for (Delay1 = 0; Delay1 < ms; Delay1++)
	{
		for (Delay2 = 0; Delay2 < 8332; Delay2++);
	}
}

Xint32 data=0;
int dout=0;
int main()
{
	//int cunt=0;
	//int state=1;
	int Status1,Status2;
	Status1 = XGpio_Initialize(&output1, XPAR_GPIO_1_DEVICE_ID);
	if (Status1 != XST_SUCCESS) {
	xil_printf("Gpio Initialization Failed\r\n");
		return XST_FAILURE;
	}

	Status2 = XGpio_Initialize(&output2, XPAR_GPIO_2_DEVICE_ID);
	if (Status2 != XST_SUCCESS) {
		xil_printf("Gpio Initialization Failed\r\n");
		return XST_FAILURE;
		}
	XGpio_Initialize(&input,XPAR_BUTTON_DEVICE_ID);

	 XGpio_SetDataDirection(&input, 1, 0X0);
	    XGpio_SetDataDirection(&output1, 1, 0X0);
	    XGpio_SetDataDirection(&output2, 1, 0X0);


		XGpio_Initialize(&input,XPAR_BUTTON_DEVICE_ID);

		XGpio_InterruptEnable(&input,BTN_INT);
		XGpio_InterruptGlobalEnable(&input);

		XIntc_Initialize(&InterruptController,INTC_DEVICE_ID);
		XIntc_SelfTest(&InterruptController);
		{
		XIntc_Connect(&InterruptController,INTC_DEVICE_INT_ID,(XInterruptHandler)DeviceDriverHandler,(void *)0);
		XIntc_Start(&InterruptController,XIN_REAL_MODE);
		XIntc_Enable(&InterruptController,INTC_DEVICE_INT_ID);
		Xil_ExceptionInit();
		Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,(Xil_ExceptionHandler)XIntc_InterruptHandler,&InterruptController);
		Xil_ExceptionEnable();
		}

    while(1)
    {
    	int i, p, tmp1, tmp2;
    	int temp[10] = { 0 };
    	int addr[10] = {0xfe, 0 };
    	int k = 16;
    	int m = 0;

    	if(InterruptProcessed){
    				break;
    			}
    					//data=1;
    					delay(10000);
    					xil_printf("%d\n",data);
    					CNN_AXI_MUL_mWriteReg(CNN_AXI_BASEADDR, CNN_AXI_REG1, data);
    	    			xil_printf("%d\n",data);
    	    			delay(5000);
    	    			dout = CNN_AXI_MUL_mReadReg(CNN_AXI_BASEADDR, CNN_AXI_REG0);
    	    			data=0;
    	    			CNN_AXI_MUL_mWriteReg(CNN_AXI_BASEADDR, CNN_AXI_REG1, data);
    	    			xil_printf("%d\n",dout);
    	    			p=dout & 0x0fffffff;
    	    			xil_printf("%d\n",p);
    	    			for (int i = 0; i < 10; i++)
    	    			{
    	    				if ((p / k) != 0)
    	    				{
    	    					k *= 16;
    	    					m++;
    	    					}
    	    				if ((p / k) == 0) break;
    	    			}
    	    			for (int i = 0; i <= m; i++)
    	    			{
    	    				temp[i] = p % 16;
    	    				p = p / 16;
    	    			}
    	    			for (int j = 0; j < 8; j++) {
    	    				if (j < m) {
    	    					tmp1 = addr[j] >> 7;
    	    					tmp2 = addr[j] << 1;
    	    					tmp2 = tmp2 & 0x0ff;
    	    					addr[j + 1] = tmp1 | tmp2;
    	    					}
    	    				else
    	    				{
    	    					addr[j + 1] = 0xff;
    	    				}
    	    			}
    	    			while(!data){
    	    			XGpio_DiscreteWrite(&output1, 1, select1(temp[0]));//DUAL SEG_7
    	    			XGpio_DiscreteWrite(&output2, 1, addr[0]);//AN
    	    			for(i=0;i<10000;i++);

    	    			XGpio_DiscreteWrite(&output1, 1, select1(temp[1]));
    	    			XGpio_DiscreteWrite(&output2, 1, addr[1]);
    	    			for(i=0;i<10000;i++);

    	    			XGpio_DiscreteWrite(&output1, 1, select1(temp[2]));//DUAL SEG_7
    	    			XGpio_DiscreteWrite(&output2, 1, addr[2]);//AN
    	    			for(i=0;i<10000;i++);


    	    			XGpio_DiscreteWrite(&output1, 1, select1(temp[3]));
    	    			XGpio_DiscreteWrite(&output2, 1, addr[3]);
    	    			for(i=0;i<10000;i++);

    	    			XGpio_DiscreteWrite(&output1, 1, select1(temp[4]));//DUAL SEG_7
    	    			XGpio_DiscreteWrite(&output2, 1, addr[4]);//AN
    	    			for(i=0;i<10000;i++);


    	    			XGpio_DiscreteWrite(&output1, 1, select1(temp[5]));
    	    			XGpio_DiscreteWrite(&output2, 1, addr[5]);
    	    			for(i=0;i<10000;i++);

    	    			XGpio_DiscreteWrite(&output1, 1, select1(temp[6]));//DUAL SEG_7
    	    			XGpio_DiscreteWrite(&output2, 1, addr[6]);//AN
    	    			for(i=0;i<10000;i++);


    	    			XGpio_DiscreteWrite(&output1, 1, select1(temp[7]));
    	    			XGpio_DiscreteWrite(&output2, 1, addr[7]);
    	    			for(i=0;i<10000;i++);

    	    			}

}
	    return XST_SUCCESS;
}


void DeviceDriverHandler(void *CallbackRef){
	//int data=0;
	if(XGpio_DiscreteRead(&input,1))
	{
		data=1;
		xil_printf("%d\n",data);


	}
	XGpio_InterruptClear(&input,BTN_INT);
}

int select1(int m)
{
	int temp=0;
	switch(m)
	{
	case 0:
		temp=0b11000000;
		break;
	case 1:
		temp=0b11111001;
		break;
	case 2:
		temp=0b10100100;
		break;
	case 3:
		temp=0b10110000;
		break;
	case 4:
		temp=0b10011001;
		break;
	case 5:
		temp=0b10010010;
		break;
	case 6:
		temp=0b10000010;
		break;
	case 7:
		temp=0b11111000;
		break;
	case 8:
		temp=0b10000000;
		break;
	case 9:
		temp=0b10010000;
		break;
	default:
		temp=0b11000000;
		break;
	}
	return temp;
}

本文cnn_uart IP是實現手寫體數字預測,通過cnn IP 掛載到匯流排上,通過microblaze中斷控制IP核。通過串列埠給板子傳送資料,最後預測結果如下圖所示:

在這裡插入圖片描述

相關文章