有时候下载别人写好的RTL IP,每次挨个连线AXI总线也挺麻烦的,而且也不直观,打包起来再用就方便多了嘛.
我这里打包的是alexforencich大佬写的I2C核,具体地址大家观摩.
https://github.com/alexforencich/verilog-i2c
新建工程并包含主要AXI所用到的三个文件.

菜单Tools->Create and Package New IP,选择Package your current project.

选好一个目录开始打包.

之后就会直接进入IP编辑,其他信息大家自己都明白自己填写了,其中端口是我们最关心的,可以看出他已经自动整理好了,如果我们要编辑某些接口使用条件或者参数,也是可以继续编辑的.

如果为了规范发布,也应该完善其他选项,比如Addressing and Memory把寄存器都填好,方便其他人嘛,还要注意RST的属性是高复位的,然后我就直接打包了.

加到我的bd里,另一个我则是以Add Module形式,自己添加了一个RTL文件,这样适配输出inout口.

接下来还要规划一下地址分布,我这里仅仅测试一下就保持默认了.

具体寄存器分布查看i2c_master_axil.v文件就知道,大佬都把注释写的非常好,
/******************************************************************************
* Copyright (C) 2023 Advanced Micro Devices, Inc. All Rights Reserved.
* SPDX-License-Identifier: MIT
******************************************************************************/
/*
* helloworld.c: simple test application
*
* This application configures UART 16550 to baud rate 9600.
* PS7 UART (Zynq) is not initialized by this application, since
* bootrom/bsp configures it to baud rate 115200
*
* ------------------------------------------------
* | UART TYPE BAUD RATE |
* ------------------------------------------------
* uartns550 9600
* uartlite Configurable only in HW design
* ps7_uart 115200 (configured by bootrom/bsp)
*/
#include <stdio.h>
#include "platform.h"
#include "xil_printf.h"
#include "xparameters.h"
#define I2C_STATUS (XPAR_I2C_MASTER_AXIL_0_BASEADDR + 0x00)
#define I2C_COMMAND (XPAR_I2C_MASTER_AXIL_0_BASEADDR + 0x04)
#define I2C_DATA (XPAR_I2C_MASTER_AXIL_0_BASEADDR + 0x08)
#define I2C_PRESCALE (XPAR_I2C_MASTER_AXIL_0_BASEADDR + 0x0C)
#define CMD_START (1<<8)
#define CMD_READ (1<<9)
#define CMD_WRITE (1<<10)
#define CMD_WR_M (1<<11)
#define CMD_STOP (1<<12)
int main()
{
uint32_t Reg;
init_platform();
*((uint32_t volatile *)(I2C_PRESCALE)) = 150;
Reg = *((uint32_t volatile *)(I2C_PRESCALE));
*((uint32_t volatile *)(I2C_COMMAND)) = CMD_START | CMD_WR_M | 0xA0;
*((uint32_t volatile *)(I2C_DATA)) = 0x0105;
*((uint32_t volatile *)(I2C_DATA)) = 0x0310;
*((uint32_t volatile *)(I2C_COMMAND)) = CMD_STOP | 0x50;
print("Hello World\n\r");
print("Successfully ran Hello World application");
cleanup_platform();
return 0;
}
实测结果
