AXI Interconnect互连内核将一个或多个 AXI 内存映射主设备连接到一个或多个内存映射从设备。
本质上设置此类缓冲是生成了一组寄存器挂在GP接口,使得能够让Arm通过amba总线去访问RAM。
AXI_GP 接口
AXI_GP 接口是直接连接主机互联和从机互联的端口的。
AXI_HP 接口具有一个 1kB 的数据 FIFO 来做缓冲 [4],但是 AXI_GP 接口与它不同,没有额外的缓冲。因此 性能就受到主机端口和从机互联的制约,突发长度为1。
这些接口仅用于通用的目的,而且不应该 被用于高性能的任务。
AXI_GP 接口的特性包括 [4]:
• 32 位数据总线宽度。
• 12 位总线端口 ID 宽度。
• 6 位从机端口 ID 宽度。
• 主机和从机端口接受一次 8 个读取和 8 个写入。
AXI_GP 接口的每个端口能支持多个外设。
通过已经给好的例子建立函数:
void AXI_REG_LIST_mWriteReg(u32 BaseAddress, unsigned RegOffset, u32 Data)
void Axi_Write(u8 *Data_addr_point,u32 Write_ByteLong){
int i;
for ( i = 0; i < Write_ByteLong; i++)
{
AXI_REG_LIST_mWriteReg(Axi_RamA_BaseAddr,i * 4,*(Data_addr_point + i));
}
}
实验结果:
Axi_Lite
一个地址存储一个字节数据,
操作的最低精度是一个字节,但AXI_GP或者说Lite支持的最低数据宽度为32位,所以一次要操作四个地址,地址的每次偏移量需要为i * 4,i为第i次操作,每次操作写入数组的第i个元素,实验中每个元素只有一个字节的长度,所以每次是将一个字节写入了四个字节长度的空间里。
官方代码:写Axi缓冲区
源码在生成XSA文件以后在src里寻找。
/**************************** 类型定义 ****************** **********/
/** * * 将值写入 AXI_REG_LIST 寄存器。执行 32 位写入。
* 如果组件以较小的宽度实现,则仅写入最不重要的数据。
* * @param BaseAddress 是 AXI_REG_LIST 设备的基地址。
* @param RegOffset 是要写入的寄存器距基址的偏移量。
* @param Data 是写入寄存器的数据。
* * @返回无。
* * @note
* C 风格签名:
* void AXI_REG_LIST_mWriteReg(u32 BaseAddress, unsigned RegOffset, u32 Data) * */
/**************************** Type Definitions *****************************/
/**
*
* Write a value to a AXI_REG_LIST register. A 32 bit write is performed.
* If the component is implemented in a smaller width, only the least
* significant data is written.
*
* @param BaseAddress is the base address of the AXI_REG_LISTdevice.
* @param RegOffset is the register offset from the base to write to.
* @param Data is the data written to the register.
*
* @return None.
*
* @note
* C-style signature:
* void AXI_REG_LIST_mWriteReg(u32 BaseAddress, unsigned RegOffset, u32 Data)
*
*/
#define AXI_REG_LIST_mWriteReg(BaseAddress, RegOffset, Data) \
Xil_Out32((BaseAddress) + (RegOffset), (u32)(Data))
读Axi缓冲区
/** * * 从 AXI_REG_LIST 寄存器读取值。执行 32 位读取。
* 如果组件以较小的宽度实现,则仅从寄存器中读取最低有效数据。最重要的数据
* 将被读取为 0。
*
* @param BaseAddress 是 AXI_REG_LIST 设备的基地址。
* @param RegOffset 是要写入的寄存器距基址的偏移量。
* * @return Data 是来自寄存器的数据。
* * @note * C 风格签名:
* u32 AXI_REG_LIST_mReadReg(u32 BaseAddress, unsigned RegOffset) *
*/
/**
*
* Read a value from a AXI_REG_LIST register. A 32 bit read is performed.
* If the component is implemented in a smaller width, only the least
* significant data is read from the register. The most significant data
* will be read as 0.
*
* @param BaseAddress is the base address of the AXI_REG_LIST device.
* @param RegOffset is the register offset from the base to write to.
*
* @return Data is the data from the register.
*
* @note
* C-style signature:
* u32 AXI_REG_LIST_mReadReg(u32 BaseAddress, unsigned RegOffset)
*
*/
#define AXI_REG_LIST_mReadReg(BaseAddress, RegOffset) \
Xil_In32((BaseAddress) + (RegOffset))
封装:
/**
*
* @param BaseAddress : 写入缓冲区基地址
* @param Addr_Offset : 写入缓冲区的地址偏移量(会占用多少空间)
* @param data :写入缓冲区的具体数据
* @return none
*
***************************************************************************/
void AxiLite_W_Single(u32 BaseAddress, u32 Addr_Offset, u32 data){
AXILITE_REG_DEEPTH256_mWriteReg(BaseAddress, Addr_Offset << 2, data);
}
/**
*
* @param BaseAddress : 写入缓冲区基地址
* @param Data_addr_point : 即将写入缓冲区的数组所在的基地址
* @param Write_ByteLong :即将写入缓冲区的数组长度
* @return none
*
***************************************************************************/
void AxiLite_W_Serial(u32 BaseAddress, u8 *Data_addr_point, u32 Write_ByteLong){
int i;
for ( i = 0; i < Write_ByteLong; i++)
{
AXILITE_REG_DEEPTH256_mWriteReg(BaseAddress,i*4 ,*(Data_addr_point + i));
}
}
/**
*
* @param BaseAddress : 读出缓冲区基地址
* @param Data_addr_point :存放读出数组的缓冲区基地址
* @param Read_ByteLong :读出数组的长度
* @return 读出数据.
* * 读出指定缓冲区的指定长度的数据存入某个区域
* * (Data_addr_point + i) = (u32) Read_Data_Origin;将所读出的数据赋值给指定的区域
*
***************************************************************************/
u32 AxiLite_R_Single(u32 BaseAddress, u32 Addr_Offset){
return AXILITE_REG_DEEPTH256_mReadReg(BaseAddress, Addr_Offset <<2);
}
/**
*
* @param BaseAddress : 读出缓冲区基地址
* @param Data_addr_point :存放读出数组的缓冲区基地址
* @param Read_ByteLong :读出数组的长度
* @return 读出数据.
* * 读出指定缓冲区的指定长度的数据存入某个区域
* * (Data_addr_point + i) = (u32) Read_Data_Origin;将所读出的数据赋值给指定的区域
*
***************************************************************************/
void AxiLite_R_Serial(u32 BaseAddress, u32 *Data_addr_point, u32 Read_ByteLong){
int i;
u32 Read_Data_Origin;
for ( i = 0; i < Read_ByteLong; i++)
{
Read_Data_Origin = AXILITE_REG_DEEPTH256_mReadReg(BaseAddress, i*4);
*(Data_addr_point + i) = (u32) Read_Data_Origin;
}
}