首页 > 其他分享 >ZYNQ AXI 片上互联的再思考:AXI GP口/axi lite

ZYNQ AXI 片上互联的再思考:AXI GP口/axi lite

时间:2024-03-18 12:35:08浏览次数:26  
标签:axi GP buf Data u32 AXI recv REG

之前笔记:

Zynq上的存储器接口与差分时钟与DDR3_zynq ddr3-CSDN博客

使用Axi Lite接口访问寄存器列表作为缓冲区_两个参数共用axi lite中一个寄存器-CSDN博客

PS与PL互联与SCU以及PG082_pl能不能用ps-gtr-CSDN博客

ZYNQ上互联的AXI主要有三种:

AXI LITE

AXI HP

AXI ACP

 

AXI LITE(GP)

用途:

通信UART,I2C,SPI,CAN等接口

作为PS存储数据到PL端方便交互的缓冲区;

特色:

32位数据位宽,不可突发;

生成方式:

用途1.自然选通产生的以上接口的以AXI GP口的形式输出的;

用途2.创建IP的时候选择AXI接口:

非常注意:

直接生成的方法至今仍存在BUG,需要采用此方法解决:

Vitis IDE 2021.1 custom AXI IP core compile error (xilinx.com)

参考操作代码:

官方参考:注意!GP口每次操作的偏移量都是4个字节!因为是32位端口!

/**************************** Type Definitions *****************************/
/**
 *
 * Write a value to a AXILITE_REG_DEEPTH256 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 AXILITE_REG_DEEPTH256device.
 * @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 AXILITE_REG_DEEPTH256_mWriteReg(u32 BaseAddress, unsigned RegOffset, u32 Data)
 *
 */
#define AXILITE_REG_DEEPTH256_mWriteReg(BaseAddress, RegOffset, Data) \
      Xil_Out32((BaseAddress) + (RegOffset), (u32)(Data))

/**
 *
 * Read a value from a AXILITE_REG_DEEPTH256 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 AXILITE_REG_DEEPTH256 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 AXILITE_REG_DEEPTH256_mReadReg(u32 BaseAddress, unsigned RegOffset)
 *
 */
#define AXILITE_REG_DEEPTH256_mReadReg(BaseAddress, RegOffset) \
    Xil_In32((BaseAddress) + (RegOffset))

/************************** Function Prototypes ****************************/
/**
 *
 * Run a self-test on the driver/device. Note this may be a destructive test if
 * resets of the device are performed.
 *
 * If the hardware system is not built correctly, this function may never
 * return to the caller.
 *
 * @param   baseaddr_p is the base address of the AXILITE_REG_DEEPTH256 instance to be worked on.
 *
 * @return
 *
 *    - XST_SUCCESS   if all self-test code passed
 *    - XST_FAILURE   if any self-test code failed
 *
 * @note    Caching must be turned off for this function to work.
 * @note    Self test may fail if data memory and device are not on the same bus.
 *
 */
XStatus AXILITE_REG_DEEPTH256_Reg_SelfTest(void * baseaddr_p);
View Code

自己封装的函数读写单个和多个:

函数1:读写多个数据;

void Axi_WriteRamA(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));
    }
}
void Axi_ReadRamB(u8 *Data_addr_point, u32 Read_ByteLong){
    int i;
    u32 Read_Data_Origin;
    for ( i = 0; i < Read_ByteLong; i++)
    {
        Read_Data_Origin = AXI_REG_LIST_mReadReg(Axi_RamB_BaseAddr, i*4);
        *(Data_addr_point + i) = (u8) Read_Data_Origin;
    }
}
View Code
void Axi_ReadRamA(u8 *Data_addr_point, u32 Read_ByteLong){
    int i;
    u32 Read_Data_Origin;
    for ( i = 0; i < Read_ByteLong; i++)
    {
        Read_Data_Origin = AXI_REG_LIST_mReadReg(Axi_RamA_BaseAddr, i*4);
        *(Data_addr_point + i) = (u8) Read_Data_Origin;
    }
}
void Axi_WriteRamB(u8 *Data_addr_point, u32 Write_ByteLong){
    int i;
    for ( i = 0; i < Write_ByteLong; i++)
    {
        AXI_REG_LIST_mWriteReg(Axi_RamB_BaseAddr,i*4 ,*(Data_addr_point  + i));
    }
}
View Code

使用示例1:

描述:

1.接收Uart数据并且校验;

2.校验成功则关闭硬中断,向CPU1发送软中断,把Uart接收到的数组写入指定的PL寄存器地址(地址A);

void Uart0_IntrHandler(void *CallBackRef, u32 Event, unsigned int EventData)
{
    if (Event == XUARTPS_EVENT_RECV_TOUT) {
        TotalReceivedCount = EventData;
        if (TotalReceivedCount == 8 
        && RecvBuffer[0] == 0x55 && RecvBuffer[1] == 0x55
        && RecvBuffer[2] == 0x00 && RecvBuffer[3] == 0x01)
        {
             XScuGic_Disable(&GIC_SGI_instance_point, Interrupt_ID_Hardware_1);
             XScuGic_Disable(&GIC_SGI_instance_point, Interrupt_ID_Hardware_0);
            Axi_WriteRamA(RecvBuffer,TotalReceivedCount);
            printf("Close SPI\n\r");
            XScuGic_SoftwareIntr(&GIC_SGI_instance_point,
                                  Interrupt_ID_SGI_15,
                                  XSCUGIC_SPI_CPU1_MASK);
        }
        else if(TotalReceivedCount == 8 && RecvBuffer[0] == 0x66)
        {
            XScuGic_Enable(&GIC_SGI_instance_point, Interrupt_ID_Hardware_0);
            printf("Open SPI\n\r");
        }
    }
    XUartPs_Recv(&Uart_Instance_point, RecvBuffer, TEST_BUFFER_SIZE);
}
View Code

使用示例2:

描述:

1.CPU1接收CPU0的软中断,据此读取地址A的数值并校验;

2.校验成功则把地址A的数值写入地址B,并且向CPU0发送软中断;

使用示例3:

描述:

CPU0接收CPU1的软中断,据此读取地址B的数值并UART发送;

void SGI_IntrHandler(void *CallBackRef){
      Axi_ReadRamB(SendBuffer,8);
      XUartPs_Send(&Uart_Instance_point, SendBuffer, 8);
      print("SG0!\n\r");
}
View Code

函数2:

/***************************** Include Files *******************************/
#include "axilite_reg_deepth256.h"

/************************** Function Definitions ***************************/

/**
*
* @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;
    }
}
View Code

使用范例:

描述:将TCP发送的数据包写入指定寄存器并且读出给PL端使用;

        if (recv_buf[0] == 0x55 &&
            recv_buf[1] == 0x55 &&
            recv_buf[2] == 0x55 &&
            recv_buf[3] == 0x55 &&
            recv_buf[4] == 0x55 &&
            recv_buf[5] == 0x55 &&
            recv_buf[6] == 0x55 &&
            recv_buf[7] == 0x55 ) {
                u32 RegAddr;
                u32 Direct_RW_Flag;
                u32 RegData = 0;
                RegAddr = recv_buf[8];
                Direct_RW_Flag = recv_buf[9];

            /* 将解析的配置数据写入指定好的PL端寄存器地址 */
            if(Direct_RW_Flag == 0){
                RegData  = recv_buf[10]<<24;
                RegData |= recv_buf[11]<<16;
                RegData |= recv_buf[12]<<8;
                RegData |= recv_buf[13]<<0;
                if(RegAddr == 1){
                    ImageWeigh = RegData;
                    xil_printf("ConfigSet ImageWeigh!\r\n");
                }
                if(RegAddr == 2){
                    ImageHeigh = RegData;
                    xil_printf("ConfigSet ImageHeigh!\r\n");
                }
                if(RegAddr == 3){
                    ReadBack_Flag = RegData;
                    xil_printf("ConfigSet ReadBack_Flag!\r\n");
                }

                AxiLite_W_Single(AXI_ConFig_list_BaseAddr, RegAddr, RegData);
                RegData = AxiLite_R_Single(AXI_ConFig_list_BaseAddr, RegAddr);
                recv_buf[10] = (RegData>>24) & 0xff;
                recv_buf[11] = (RegData>>16) & 0xff;
                recv_buf[12] = (RegData>>8 ) & 0xff;
                recv_buf[13] = (RegData>>0 ) & 0xff;
                if((lwip_send(sock, recv_buf, read_bytes, 0))<0){
                    xil_printf("%s : Send Error!\r\n",sock);
                    break;
                }
            }
        }
View Code

 

标签:axi,GP,buf,Data,u32,AXI,recv,REG
From: https://www.cnblogs.com/VerweileDoch/p/18080046

相关文章

  • 轻松创建基于 GPT-4 的 AI 原生应用 - Dify
    Dify 是一个易用的 LLMOps 平台,旨在让更多人可以创建可持续运营的原生AI应用。Dify提供多种类型应用的可视化编排,应用可开箱即用,也能以后端即服务的API提供服务。LLMOps(LargeLanguageModelOperations)是一个涵盖了大型语言模型(如GPT系列)开发、部署、维护和优化的一......
  • ChatGPT:从对话到文献,如何利用AI成就完美论文?
    ChatGPT无限次数:点击直达引言:在当今信息爆炸的时代,撰写一篇完美的论文变得至关重要。然而,对于很多人来说,论文写作是一个具有挑战性的任务。幸运的是,人工智能的迅猛发展为我们的学术创作提供了新的可能性。在本文中,将介绍一种强大的自然语言处理模型——ChatGPT,它将成为您的......
  • 文心一言 VS 讯飞星火 VS chatgpt (217)-- 算法导论16.2 4题
    四、Gekko教授一直梦想用直排轮滑的方式横穿北达科他州。他计划沿U.S.2号高速公路横穿,这条高速公路从明尼苏达州东部边境的大福克斯市到靠近蒙大拿州西部边境的威利斯顿市。教授计划带两公升水,在喝光水之前能滑行m英里(由于北达科他州地势相对平坦,教授无需担心在上坡路段喝......
  • 使用 LogProperties source generator 丰富日志
    Nuget包 Microsoft.Extensions.Telemetry.Abstractions包含的新的日志记录sourcegenerator,它支持使用[LogProperties]将整个对象作为State与日志一起记录。我将展示一种方法来控制如何使用[LogProperties]对象自动丰富日志。示例您可以使用日志sourcegenerator创建一个如下......
  • Linux监控CPU和GPU
    监控显卡占用情况watch-n2nvidia-smicpupower安装sudoaptinstalllinux-tools-commonCPU实时频率查看watch-n1sudocpupowermonitor查看cpu频率watch-n0"cat/proc/cpuinfo|grep-imhz"查看cpu频率模式cpupowerfrequency-info查看当前所有CPU的信息su......
  • “成像光谱遥感技术中的AI革命:ChatGPT应用指南“
    遥感技术主要通过卫星和飞机从远处观察和测量我们的环境,是理解和监测地球物理、化学和生物系统的基石。ChatGPT是由OpenAI开发的最先进的语言模型,在理解和生成人类语言方面表现出了非凡的能力。本文重点介绍ChatGPT在遥感中的应用,人工智能在解释复杂数据、提供见解和帮助决策过......
  • 一键升级 ChatGPT Plus
    前言虽然目前ChatGPT4.0已经推出了有一段时间了,但是由于众所周知的原因,国内仍有许多人还没有体验过ChatGPT4.0,是因为ChatGPTPlus的升级还是存在一定门槛的,所以,本文将教你如何一键升级ChatGPTPlus。为什么升级ChatGPTPlusChatGPT4.0比ChatGPT3.5更加强大......
  • 时间序列预测的零样本学习是未来还是炒作:TimeGPT和TiDE的综合比较
    最近时间序列预测预测领域的最新进展受到了各个领域(包括文本、图像和语音)成功开发基础模型的影响,例如文本(如ChatGPT)、文本到图像(如Midjourney)和文本到语音(如ElevenLabs)。这些模型的广泛采用导致了像TimeGPT[1]这样的模型的出现,这些模型利用了类似于它们在文本、图像和语音方面获......
  • 免费体验一个月微软Copilot Pro!在Office套件里使用GPT-4!
    大家好,我是木易,一个持续关注AI领域的互联网技术产品经理,国内Top2本科,美国Top10CS研究生,MBA。我坚信AI是普通人变强的“外挂”,所以创建了“AI信息Gap”这个公众号,专注于分享AI全维度知识,包括但不限于AI科普,AI工具测评,AI效率提升,AI行业洞察。关注我,AI之路不迷路,2024我们一起变......
  • 文心一言 VS 讯飞星火 VS chatgpt (216)-- 算法导论16.2 3题
    三、假定在0-1背包问题中,商品的重量递增序与价值递减序完全一样。设计一个高效算法求此背包问题的变形的最优解,证明你的算法是正确的。如果要写代码,请用go语言。文心一言:在0-1背包问题中,如果商品的重量递增序与价值递减序完全一样,那么我们可以利用这个特性设计一种高效的算法......