nexys4DDR 實現自定義IP核掛載到axi_4匯流排
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核。通過串列埠給板子傳送資料,最後預測結果如下圖所示:
相關文章
- 在vue專案中自定義事件匯流排eventHubVue事件
- 事件匯流排的設計與實現事件
- Highcharts 實現自定義匯出圖片
- 匯流排
- WebWorker與WebSocket實現前端訊息匯流排Web前端
- FFT Vivado IP核實現FFT
- 實現一個事件匯流排(vue.prototype.$bus)?事件Vue
- 元件間通訊--利用mitt實現事件匯流排元件MIT事件
- 如何在 pyqt 中實現全域性事件匯流排QT事件
- 如何在 JavaScript 中實現 Event Bus(事件匯流排)JavaScript事件
- 事件匯流排事件
- 基於事件匯流排EventBus實現郵件推送功能事件
- 學習筆記-Verilog實現IIC匯流排協議筆記協議
- 6.匯流排
- SpringBoot自定義攔截器實現IP白名單功能Spring Boot
- 將Abp預設事件匯流排改造為分散式事件匯流排事件分散式
- I2C匯流排 | I2C匯流排介紹
- ARM 匯流排協議協議
- Vue事件匯流排(EventBus)Vue事件
- Can匯流排介紹
- Vue 事件中央匯流排Vue事件
- 在 .NET 中深入瞭解事件匯流排的使用與實現事件
- 重建Base Overlay並載入自定義HLS IP
- 【vue外掛篇】vue-options-events 事件匯流排觸發Vue事件
- 最佳實踐:負載均衡SLB支援自定義VPC例項IP地址負載
- 從零開始實現簡單 RPC 框架 3:配置匯流排 URLRPC框架
- 大資料匯流排(DataHub)大資料
- CAN匯流排原理_學習
- 序列匯流排的學習
- I2C 匯流排
- 計算匯流排頻寬
- PCI匯流排基本概念
- 【Maven實戰技巧】「外掛使用專題」Maven-Assembly外掛實現自定義打包Maven
- 【JAVA】自定義類載入器實現類隔離Java
- 自定義SpringMVC部分實現SpringMVC
- 自定義實現Complex類
- Android自定義拍照實現Android
- Net 實現自定義Aop