PYNQ上手笔记 | ⑥HDL设计IP核

现在人工智能非常火爆,一般的教程都是为博硕生准备的,太难看懂了,分享一个非常适合小白入门的教程,不仅通俗易懂而且还很风趣幽默,点☞这里​​​​​​​☜进入传送门~

1.实验目的

用HDL语言+Vivado创建一个挂载在AXI总线上的自定义IP核

2.实验步骤

2.1.创建一个新的项目

PYNQ上手笔记 | ⑥HDL设计IP核_第1张图片

2.2.调用Create and Package IP Wizard,创建一个新的AXI-Lite从机ip

选择Tools->Create and Package IP
PYNQ上手笔记 | ⑥HDL设计IP核_第2张图片

PYNQ上手笔记 | ⑥HDL设计IP核_第3张图片

PYNQ上手笔记 | ⑥HDL设计IP核_第4张图片

PYNQ上手笔记 | ⑥HDL设计IP核_第5张图片

PYNQ上手笔记 | ⑥HDL设计IP核_第6张图片

编辑创建的IP
PYNQ上手笔记 | ⑥HDL设计IP核_第7张图片

  • led_controller_v1_0.v — 实例化了所有的AXI-Lite接口,在这种情况下,只有一个接口存在
  • led_controller_v1_0_S00_AXI.v — 包含了处理PL外设与PS端软件的AXI4-Lite接口功能
    打开led_controller_v1_0_S00_AXI.v文件,找到Users to add ports here,然后在其后添加需要的端口:
    PYNQ上手笔记 | ⑥HDL设计IP核_第8张图片

然后在文件最后,找到Add user logic here,然后在其后添加逻辑功能代码:

保存文件,打开led_controller_v1_0.v文件,找到Users to add ports here,添加端口:
PYNQ上手笔记 | ⑥HDL设计IP核_第9张图片

在顶层文件中例化刚刚我们添加的端口,保存文件:
PYNQ上手笔记 | ⑥HDL设计IP核_第10张图片

更新IP核
PYNQ上手笔记 | ⑥HDL设计IP核_第11张图片

打包IP核
PYNQ上手笔记 | ⑥HDL设计IP核_第12张图片

PYNQ上手笔记 | ⑥HDL设计IP核_第13张图片

PYNQ上手笔记 | ⑥HDL设计IP核_第14张图片

然后关闭这个工程即可,ip核创建成功。

2.3.添加ip核到Block Design中进行设计

创建Block Design:
PYNQ上手笔记 | ⑥HDL设计IP核_第15张图片

点击Add IP,搜索led,添加led_controllerIP:
PYNQ上手笔记 | ⑥HDL设计IP核_第16张图片

因为LEDs_out要连接板载LED,所以点击引脚,按下ctrl+t导出引脚:
PYNQ上手笔记 | ⑥HDL设计IP核_第17张图片

添加Zynq ps核,自动连线:
PYNQ上手笔记 | ⑥HDL设计IP核_第18张图片

按下F6验证设计:
PYNQ上手笔记 | ⑥HDL设计IP核_第19张图片

创建Block Design 的HDL文件:
PYNQ上手笔记 | ⑥HDL设计IP核_第20张图片

添加LED引脚约束文件:
PYNQ上手笔记 | ⑥HDL设计IP核_第21张图片

PYNQ上手笔记 | ⑥HDL设计IP核_第22张图片

PYNQ上手笔记 | ⑥HDL设计IP核_第23张图片

##LEDs
set_property -dict { PACKAGE_PIN R14   IOSTANDARD LVCMOS33 } [get_ports { LEDs_out_0[0] }]; #IO_L6N_T0_VREF_34 Sch=LEDs_out_0[0]
set_property -dict { PACKAGE_PIN P14   IOSTANDARD LVCMOS33 } [get_ports { LEDs_out_0[1] }]; #IO_L6P_T0_34 Sch=LEDs_out_0[1]
set_property -dict { PACKAGE_PIN N16   IOSTANDARD LVCMOS33 } [get_ports { LEDs_out_0[2] }]; #IO_L21N_T3_DQS_AD14N_35 Sch=LEDs_out_0[2]
set_property -dict { PACKAGE_PIN M14   IOSTANDARD LVCMOS33 } [get_ports { LEDs_out_0[3] }]; #IO_L23P_T3_35 Sch=LEDs_out_0[3]

2.4.生成Bitstream,打开实现设计,导出硬件文件,运行SDK

PYNQ上手笔记 | ⑥HDL设计IP核_第24张图片

2.5.创建一个空的应用工程

File->New->Application Project,选择创建一个空工程:

2.6.添加驱动库

光标选中led_test_bsp之后再进行下面的操作!!!

选择Xilinx->Repositories
PYNQ上手笔记 | ⑥HDL设计IP核_第25张图片

添加ip核所在目录,添加完了之后SDK会自动扫描所添加的目录,然后重新编译工程来添加新的驱动文件:

检查一下库有没有被分派到LED_Controller外设,打开system.mss文件,可以看到外设驱动中存在led_controller_0:
PYNQ上手笔记 | ⑥HDL设计IP核_第26张图片

点击最上面modify this BSP's Setting检查驱动设置:
PYNQ上手笔记 | ⑥HDL设计IP核_第27张图片

至此,led_controlerip核的硬件设计完毕,BSP驱动添加完毕,可以开始写应用测试程序了。

2.7.编写应用代码

先在src文件夹下创建一个C文件:
PYNQ上手笔记 | ⑥HDL设计IP核_第28张图片

/**
 * @file 	led_test.c
 * @brief	led_controler ip test
 * @author  mculover666
 * @date	2018/11/10
 * */
#include "xparameters.h"
#include "xil_io.h"			//led_controller.h中用到了Xil_Out32
#include "led_controller.h"
#include "xil_printf.h"


#define LED_BASE_ADDR	XPAR_LED_CONTROLLER_0_S00_AXI_BASEADDR
#define LED_REG0		0

#define	DELAY 50000000

int main()
{
	int temp = 0;
	int led_value = 0;
	int i = 0;

    xil_printf("led_controller ip test\r\n");
    xil_printf("----------------------\r\n");

   while(1)
	{
	   	/* write reg0 */
		LED_CONTROLLER_mWriteReg(LED_BASE_ADDR,LED_REG0,led_value);

		/* read reg0 */
		temp = LED_CONTROLLER_mReadReg (LED_BASE_ADDR,LED_REG0);

		/* show value */
		xil_printf("led = %d",led_value);
		xil_printf("\ttemp = %d\r\n",temp);

		if(led_value < 15)
			led_value++;
		else
			led_value = 0;

		for(i=0;i<DELAY;i++);

	}
}

2.9.配置运行,观察结果

PYNQ上手笔记 | ⑥HDL设计IP核_第29张图片

PYNQ上手笔记 | ⑥HDL设计IP核_第30张图片

3.实验总结

这个实验做了很长时间,最后看着灯思考了很长时间:

  • 从实验的角度来说说:用HDL创建一个挂载在AXI总线上的ip核去控制LED,然后在存储器映射下这个ip核的四个寄存器会有自己的地址,CPU靠这个地址来访问寄存器,为了操作简单,一般会有一个基地址,其余寄存器是相对这个基地址的偏移,所以控制代码只需要读写寄存器就可以了;
  • 从嵌入式原理的角度来说,其实设计都是基于寄存器的,硬件靠寄存器的数据来工作,寄存器挂载在总线上,所以寄存器会有一个地址(寄存器映射),我们通过指针就可以访问内存空间中这个地址处的数据;
  • 从嵌入式发展的角度来说,通常寄存器地址映射都是由厂商出厂时候映射好的,我们只需要查看芯片参考手册去编程,现在整个硬件可以自己设计,寄存器地址映射只是在一个固定的区间段内(AXI 从机地址1G),变的更加灵活了,也说明了整个数字系统的设计正在由板上设计转入片上设计,原来由一块板子才能搞定的任务,现在只需要一个芯片即可~

你可能感兴趣的:(#,Pynq/Zynq实战教程,FPGA开发)