当前位置: 首页 > news >正文

ZYNQ笔记(十四):基于 BRAM 的 PS、PL 数据交互

版本:Vivado2020.2(Vitis)

实验任务:

        PS 将字符串数据写入BRAM,再将数据读取出来;PL 从 BRAM 中读取数据,bing。通过 ILA 来观察读出的数据,与前面串口打印的数据进行对照(检查是否正确读出)。

目录

一、介绍

1. BRAM(Block RAM)

2. AXI BRAM Controller         

二、硬件设计

1. 整体系统框图

2. 配置 BRAM

3. 配置 AXI BRAM Controller

4. 自定义IP核(pl_bram_rd)

5. 最终 bd 设计

三、软件设计

四、效果


一、介绍

1. BRAM(Block RAM)

        BRAM(Block RAM) 是 Xilinx Zynq SoC 内部的嵌入式高速静态存储器(SRAM),分布在 FPGA 可编程逻辑(PL)部分,但也可被处理器系统(PS)直接访问。主要特点:

特性说明
高速访问1~2 个时钟周期完成读写,远快于外部 DDR(通常需数十周期)
低功耗低功耗,片上存储无需外部总线交互
双端口架构支持双端口(可独立读写),可配置为单端口或真双端口模式
存储容量每块 36Kb(可拆分为 2×18Kb),器件集成数量:几十至数百块
初始化方式支持 COE 文件预加载或运行时写入
典型用途高速缓存、查找表、PS-PL 数据共享、跨时钟域同步
ECC 支持可选校验功能

2. AXI BRAM Controller         

        AXI BRAM Controller 是 Xilinx FPGA 和 Zynq SoC 中常用的 IP 核,用于通过 AXI 总线协议 访问 BRAM (Block RAM)。它允许 PS 端或 DMA 控制器通过标准 AXI 接口高效读写 BRAM,同时支持 PL(FPGA 逻辑)和 PS(处理器系统)之间的数据共享。

特性说明
支持的 AXI 协议AXI4(高性能)、AXI4-Lite(简化版)
数据位宽32/64/128/256/512 位(需匹配 BRAM 配置)
突发传输AXI4 支持突发(Burst)读写,提升吞吐量
ECC 支持可选,增加数据校验功能
低延迟配置可配置访问延迟
多主设备支持多个 Master(如 CPU + DMA)可共享同一 BRAM

二、硬件设计

1. 整体系统框图

        PS端:除了 基本的 DDR 和 UART 还使用到了 AXI 接口,因此如时钟、复位、AXI接口 都需要保留和配置。 

        PL 端:存储数据的 BRAM 的 IP 核、实现对 BRAM 写入数据的 AXI BRAM 控制器 IP 核、读取 BRAM IP 核数据的自定义的 IP 核(pl_bram_rd)。

2. 配置 BRAM

        即添加 Block Memory Generator IP 核,配置如下:

        BRAM IP 核支持两种模式,一种是独立模式(Stand Alone),在此模式下,可以自由配置 RAM 的数 据深度和宽度;另一种是 BRAM 控制器模式(BRAM Controller),在此模式下,地址和数据默认为 32 位, 由于本次实验添加了 BRAM 控制器 IP 核,因此 BRAM 模式选择 BRAM 控制器模式。

        存储类型(Memory Type)设置为“True Dual Port RAM” 真双端口 RAM。一端连接 PL 读 BRAM IP 核,另一端连接 BRAM 控制器。

        来到其他选项:取消使能安全电路(如果勾选使能安全电路,BRAM 端口会增加 rst_busy 端口,用于表示何时可以访问 BRAM。)

        在 AXI BRAM Controller 模式下,BRAM 的 we写使能信号为 4 位,这是为了支持 按字节写入(Byte-Write)功能,允许对 32 位数据(4 字节)中的特定字节进行单独写入,而无需覆盖整个字。以下是详细说明:

  • AXI 总线特性:AXI 协议支持字节级写入(通过 WSTRB 信号),因此 BRAM Controller 需将 AXI 的字节使能信号转换为 BRAM 的 we[3:0]

  • 数据对齐:32 位 BRAM 数据(4 字节)中,每个 we 位对应一个字节的写使能:

    • we[0]:控制 字节 0(数据位 [7:0]

    • we[1]:控制 字节 1(数据位 [15:8]

    • we[2]:控制 字节 2(数据位 [23:16]

    • we[3]:控制 字节 3(数据位 [31:24]

3. 配置 AXI BRAM Controller

        AXI Protocol(AXI 协议)选择的是 AXI4_Lite,本实验只需发送一段开源电子网网址的字符串,因此选择适用于低吞吐率存储映射的 AXI4_Lite 接口即可满足传输需求。

        Data Width(数据位宽)固定为默认的 32 位,由于 AXI4 总线为字节寻址,因此在映射到 BRAM 地址时,需要按 4 字节寻址。

        BRAM 接口数 1,本次 BRAM 控制器只需要读写 BRAM 的一个端口,

        此外 Memory Depth(存储深度)不可以设置,寻址 BRAM 的存储深度是在 Address Editor 里设置。读取延时默认1个时钟周期。ECC 用于数据错误纠正与检查,不使能。所有配置如下:

4. 自定义IP核(pl_bram_rd)

        自定义 IP 核的设计和封装可参考:ZYNQ笔记(六):自定义IP核-LED呼吸灯 。可以直接点击菜单栏的 “Tools”,选择 “Creat and Package New IP…” 在当前工程目录快速进行自定义 IP 核的创建,如下图所示:

        需要注意创建的是 带 AXI 接口的 IP 

        IP 默认在工程目录的上一级目录创建目录ip_repo (/../ip_repo) ,这里去掉一个点让他创建在当前工程目录下(/./ip_repo) :

        AXI 接口类型设置为 Lite 和前面保持一致,接口模式为从。Next、Finish。

        在IP Catolog 内找到 整个自定义 IP pl_bram_rd,右键进行编辑。pl_bram_rd 里面所添加的自定义verilog模块是直接使用的正点原子的 bram_rd 模块,模块引出了 bram 接口并实现了对 bram 的读操作,控制信号在例化时相依分配寄存器即可,这样 PS 端通过读相应寄存器实现对 PL 端 自定义IP核 pl_bram_rd 的控制。

bram_rd 模块

/*BRAM读数据 模块例化bram_rd bram_rd(.clk            (S_AXI_ACLK ), //时钟信号.rst_n          (S_AXI_ARESETN), //复位信号//PS端输入的控制信号(分配三个寄存器进行控制).start_rd       (slv_reg0[0]), //读开始信号(上升沿有效).start_addr     (slv_reg1   ), //读开始地址  .rd_len         (slv_reg2   ), //读数据的长度//BRAM端口     .ram_clk        (ram_clk    ), //RAM时钟.ram_rst        (ram_rst    ), //RAM复位信号,高有效.ram_en         (ram_en     ), //RAM工作使能信号.ram_we         (ram_we     ), //RAM写使能信号.ram_addr       (ram_addr   ), //RAM地址.ram_wr_data    (ram_wr_data), //RAM要写入的数据.ram_rd_data    (ram_rd_data)  //RAM中读出的数据);
*///模块实现对BRAM的读取操作(BRAM为控制模式为 BRAM Contrulor 控制)
module bram_rd(input                clk        , //时钟信号input                rst_n      , //复位信号//控制信号input                start_rd   , //读开始信号(上升沿有效)input        [31:0]  start_addr , //读开始地址  input        [31:0]  rd_len     , //读数据的长度//BRAM端口output               ram_clk    , //RAM时钟output               ram_rst    , //RAM复位信号,高有效output  reg          ram_en     , //RAM工作使能信号output  reg  [3:0]   ram_we     , //RAM写使能信号output  reg  [31:0]  ram_addr   , //RAM地址output  reg  [31:0]  ram_wr_data, //RAM要写入的数据input        [31:0]  ram_rd_data  //RAM中读出的数据
);
reg  [1:0]   flow_cnt;//流程计数
reg          start_rd_d0;
reg          start_rd_d1;assign ram_rst = 1'b0;
assign ram_clk = clk ;//读开始信号上升沿标志信号
wire   pos_start_rd; 
assign pos_start_rd = ~start_rd_d1 & start_rd_d0;//延时两拍,采start_rd信号的上升沿
always @(posedge clk or negedge rst_n) beginif(!rst_n) beginstart_rd_d0 <= 1'b0;   start_rd_d1 <= 1'b0; endelse beginstart_rd_d0 <= start_rd;   start_rd_d1 <= start_rd_d0;     end
end//判断读开始信号,从RAM中读出数据
always @(posedge clk or negedge rst_n) beginif(!rst_n) beginflow_cnt    <= 2'd0;ram_en      <= 1'b0;ram_we      <= 4'd0;ram_addr    <= 32'd0;end//通过计数实现的简单状态机else begincase(flow_cnt)2'd0 : beginif(pos_start_rd) beginram_en   <= 1'b1;ram_addr <= start_addr;flow_cnt <= flow_cnt + 2'd1;endend2'd1 : beginif(ram_addr - start_addr == rd_len - 4) begin  //数据读完(读完差值为rd_len-4)ram_en   <= 1'b0;flow_cnt <= flow_cnt + 2'd1;endelseram_addr <= ram_addr + 32'd4; //地址累加4(,一次读32位4个字节,一个字节对应一个地址)end2'd2 : beginram_addr <= 32'd0; flow_cnt <= 2'd0;endendcaseend
endendmodule

        接着就是把 bram_rd 模块例化到 官方AXI 接口模块中并添加端口定义:

AXI接口模块例化、添加端口定义:

AXI 接口顶层模块添加端口定义:

        接着保存后综合,并打包IP核(参考:ZYNQ笔记(六):自定义IP核-LED呼吸灯 )。注意再PORT 栏部分,为了使 IP 核最后在 bd 视图简洁规范,这里需要对自定义的端口封装成一个BRAM的总线接口并匹配端口类型(也可以不设置,不过结果就是db视图中IP核自定义端口全部罗列在视图上不能缩略为接口,同时运行自动连线时不能自动连接BRAM,需要手动连线)

        找到端口,可能有端口被纳入到其他组里面,选中右键 Remove Interface 把它移出来即可:

        选中所有自定义端口右键添加总线接口,接口定义设置为官方的bram接口,自己进行命名,模式选“Master”主模式(因为是要读写BRAM模块)

        为自定义的端口添加接口映射(左右对应选中点击Map Ports):

        最后添加自动计算参数,这里直接全部添加过去(Vivado 根据连接的总线或关联 IP 自动推导,这里没有进行特定的设置,直接选“自动”即可)

       完成后PORT栏可以查看接口情况,GUI视图栏也可以看到这些端口被封装为一个接口了:

        最后打包IP即可。注意 : 在Vitis 开发环境下,需要修改自定义IP核的 Makefile 文件,如果不修改,当包含该 IP 的硬件(xsa)文件导出 到 vitis 后,对 vitis 工程进行编译就会报错,报错信息为“xxx.h: No such file or directory”。因此需要在使用该 IP 前完成修改: Makefile 修改方法

5. 最终 bd 设计

        添加完自定义IP核后可以运行自动连接,为了保险起见手动设置要自定义IP核要连接的 BRAM 避免出错。

        接着需要设置地址映射,设置地址范围也会间接定义 BRAM 的大小。这里读/写同一 bram 就都设置为 4K(单位字节),也定义 BRAM 深度大小为 1K (BRAM 数据位宽32位 4字节)。BRAM 控制器 和 自定义 IP(BRAM读控制器) 的地址范围不能重合。

        除了定义 BRAM 大小,两个 bram 控制器需要设置映射地址和范围是为了定义可访问的 BRAM 地址,确保模块能够准确读写数据。尽管已经通过连接明确了物理关系(接口连接),地址映射仍然是必要的,实际设置的是 BRAM 的映射地址,而非 BRAM 控制器本身,以确保控制器能正确进行数据访问。      

        最后整体 bd 设计部分如图所示:设计检查、Generate Output Products、 Create HDL Wrapper、管脚约束(没有PL管脚,忽略这一步)、Gnerate Bitstream、Export Hardware(包含比特流文件)、启动Vitis

三、软件设计

#include "xil_printf.h"
#include "xparameters.h"
#include "pl_bram_rd.h"  	//自定义IP头文件(包含对IP寄存器进行读写的函数)
#include "xbram.h"			//AXI BRAM Controller IP头文件(包含使用该IP进行BRAM读写的函数)
#include "stdio.h"
#include "sleep.h"//===================用户自定义宏===================//
#define BRAM_BASEADDR       XPAR_BRAM_0_BASEADDR	//BRAM器件(BRAM IP核) 基地址#define BRAM_RD_IP			XPAR_PL_BRAM_RD_0_S00_AXI_BASEADDR 	//自定义IP核(pl_bram_rd)寄存器基地址
#define BRAM_RD_START_RD	PL_BRAM_RD_S00_AXI_SLV_REG0_OFFSET 	//start_rd  对应寄存器(slv_reg0)地址偏移量(pl_bram_rd.h中查看)
#define BRAM_RD_STRAT_ADDR	PL_BRAM_RD_S00_AXI_SLV_REG1_OFFSET 	//start_addr对应寄存器(slv_reg1)地址偏移量
#define BRAM_RD_RD_LEN		PL_BRAM_RD_S00_AXI_SLV_REG2_OFFSET 	//rd_len    对应寄存器(slv_reg2)地址偏移量#define STRAT_ADDR 			0	//读起始地址(从0开始)
#define BRAM_DATA_BYTE 		4 	//BRAM 数据字节数(32位宽 4字节)//===================函数变量声明===================//
void BRAM_Ctrl_Wr();	//BRAM控制器写数据
void BRAM_Ctrl_Rd();	//BRAM控制器读数据
void PL_BRAM_RD_Rd();	//自定义IP核(pl_bram_rd)读数据int  wr_len;				//写入数据长度
char wr_buff[50] = "Hello"; //写入数据(字符数组)
char rd_buff[50] = "";		//读出数据//======================主函数======================//
int main()
{while(1){xil_printf("Write Char Data : %s\r\n", wr_buff);  // 打印待写入数据数据wr_len = strlen(wr_buff);	//获取字符串长度BRAM_Ctrl_Wr();				//BRAM控制器写数据BRAM_Ctrl_Rd();				//BRAM控制器读数据PL_BRAM_RD_Rd();			//自定义IP核(pl_bram_rd)读数据sleep(3);					//每隔3秒执行一次}return 0;
}//================BRAM控制器写数据================//
void BRAM_Ctrl_Wr()
{//用XBram_WriteReg一次写入一个字符,用for循环遍历写入所有字符for(int i=0; i<wr_len; i++){//XBram_WriteReg(BRAM基地址,偏移量,写入数据),这里一次偏移4字节是因为BRAM数据位宽32位4字节,不过每次只写1个字符XBram_WriteReg(BRAM_BASEADDR, i*BRAM_DATA_BYTE, wr_buff[i]);}xil_printf("BRAM Write done! \r\n");
}//================BRAM控制器读数据================//
void BRAM_Ctrl_Rd()
{xil_printf("Read Char Data : ");//用XBram_WriteReg一次读取一个字符,用for循环遍历读取所有字符for(int i=0; i<wr_len; i++){//XBram_ReadReg(BRAM基地址,偏移量)rd_buff[i] = XBram_ReadReg(BRAM_BASEADDR, i*BRAM_DATA_BYTE);xil_printf("%c",rd_buff[i]);}xil_printf("\r\n");
}//===========自定义IP核(pl_bram_rd)读数据===========//
void PL_BRAM_RD_Rd()
{PL_BRAM_RD_mWriteReg(BRAM_RD_IP, BRAM_RD_RD_LEN, wr_len*BRAM_DATA_BYTE); 			//设置读数据长度PL_BRAM_RD_mWriteReg(BRAM_RD_IP, BRAM_RD_STRAT_ADDR, STRAT_ADDR*BRAM_DATA_BYTE); 	//设置读起始地址//产生读开始信号有效上升沿PL_BRAM_RD_mWriteReg(BRAM_RD_IP, BRAM_RD_START_RD, 1); 			//拉高读开始信号PL_BRAM_RD_mWriteReg(BRAM_RD_IP, BRAM_RD_START_RD, 0); 			//拉低读开始信号
}

四、效果

        PS 端:先打印待写入数据,写入后将数据读取并打印。可看到前后一致说明写入数据无误

        PL 端:要用到 ILA 查看 自定义IP 核读取的数据是否正确,手动添加一个 ILA IP 核并在system_warper 中进行例化(修改保存后需要重新走一遍导出xac文件之前的流程)。

        不过这样到最后并没有实现PL到PS的数据传输,可以考虑自定义IP核加一个中断输出,并重新修改功能,实现读取数据后再接着最后一个地址开始,再把数据写到BRAM上,然后产生一个高脉冲信号(中断信号)时PS端得到中断开读数据检查两端数据是否一致:参考文章
ZYNQ—BRAM全双工PS_PL数据交互(开源) 

        关于自定义IP核的中断(BD设计里面需要给ZYNQ添加中断端口),我这里也有一个可参考的模板,中断类型位上升沿中断:

#include "xil_printf.h"
#include "xparameters.h"
#include "pl_bram_rd.h"  	//自定义IP头文件(包含对IP寄存器进行读写的函数)
#include "xbram.h"			//AXI BRAM Controller IP头文件(包含使用该IP进行BRAM读写的函数)
#include "xscugic.h"
#include "stdio.h"//===================用户自定义宏===================//
#define BRAM_BASEADDR       XPAR_BRAM_0_BASEADDR	//BRAM器件(BRAM IP核) 基地址#define BRAM_RD_IP			XPAR_PL_BRAM_RD_0_S00_AXI_BASEADDR 	//自定义IP核(pl_bram_rd)寄存器基地址
#define BRAM_RD_START_RD	PL_BRAM_RD_S00_AXI_SLV_REG0_OFFSET 	//start_rd  对应寄存器(slv_reg0)地址偏移量(pl_bram_rd.h中查看)
#define BRAM_RD_STRAT_ADDR	PL_BRAM_RD_S00_AXI_SLV_REG1_OFFSET 	//start_addr对应寄存器(slv_reg1)地址偏移量
#define BRAM_RD_RD_LEN		PL_BRAM_RD_S00_AXI_SLV_REG2_OFFSET 	//rd_len    对应寄存器(slv_reg2)地址偏移量#define STRAT_ADDR 			0	//读起始地址(从0开始)
#define BRAM_DATA_BYTE 		4 	//BRAM 数据字节数(32位宽 4字节)#define INTC_DEVICE_ID		XPAR_SCUGIC_SINGLE_DEVICE_ID	  	//宏定义中断控制器(GIC)ID
#define BRAM_RD_IP_ID  		XPAR_PL_BRAM_RD_0_DEVICE_ID       	//自定义IP核(pl_bram_rd)器件ID
#define BRAM_RD_IP_INTR_ID	XPAR_FABRIC_PL_BRAM_RD_0_INTR_INTR 	//宏定义GPIO中断号(每个器件都有中断号,xparameters.h查询)//===================函数变量声明===================//
XScuGic Intc;			//中断控制器驱动实例void BRAM_Ctrl_Wr ();	//BRAM控制器写数据
void BRAM_Ctrl_Rd ();	//BRAM控制器读数据
void PL_BRAM_RD_Rd();	//自定义IP核(pl_bram_rd)读数据
void Set_Intr_Sys(XScuGic *GicInstancePtr, u16 DeviceIntrID);    //建立中断系统
void IntrHandler();		//中断处理函数int  wr_len;		      //写入数据长度
char wr_buff[] = "ABC"; //写入数据(字符数组)//======================主函数======================//
int main()
{//建立中断系统Set_Intr_Sys(&Intc, BRAM_RD_IP_INTR_ID);wr_len = strlen(wr_buff);	//获取字符串长度BRAM_Ctrl_Wr ();			//BRAM控制器写数据BRAM_Ctrl_Rd ();			//BRAM控制器读数据PL_BRAM_RD_Rd();			//自定义IP核(pl_bram_rd)读写数据while(1)return 0;
}//================BRAM控制器写数据================//
void BRAM_Ctrl_Wr()
{//用XBram_WriteReg一次写入一个字符,用for循环遍历写入所有字符for(int i=0; i<wr_len; i++){//XBram_WriteReg(BRAM基地址,偏移量,写入数据),这里一次偏移4字节是因为BRAM数据位宽32位4字节,不过每次只写1个字符//读写地址=基地址+偏移量XBram_WriteReg(BRAM_BASEADDR, i*BRAM_DATA_BYTE, wr_buff[i]);}xil_printf("BRAM Write Finish! \r\n");
}//================BRAM控制器读数据================//
void BRAM_Ctrl_Rd()
{int r_data;xil_printf("Read the Written Data : ");//用XBram_WriteReg一次读取一个字符,用for循环遍历读取所有字符for(int i=0; i<wr_len; i++){//XBram_ReadReg(BRAM基地址,偏移量)//读写地址=基地址+偏移量r_data = XBram_ReadReg(BRAM_BASEADDR, i*BRAM_DATA_BYTE);xil_printf("%c",r_data);}xil_printf("\r\n");
}//===========自定义IP核(pl_bram_rd)读数据===========//
void PL_BRAM_RD_Rd(u32 addr)
{xil_printf("START the custom IP: \r\n");PL_BRAM_RD_mWriteReg(BRAM_RD_IP, BRAM_RD_RD_LEN, wr_len*BRAM_DATA_BYTE); 		 //设置读数据长度PL_BRAM_RD_mWriteReg(BRAM_RD_IP, BRAM_RD_STRAT_ADDR, STRAT_ADDR*BRAM_DATA_BYTE); //设置读起始地址//产生读开始信号有效上升沿PL_BRAM_RD_mWriteReg(BRAM_RD_IP, BRAM_RD_START_RD, 1); 	//拉高读开始信号PL_BRAM_RD_mWriteReg(BRAM_RD_IP, BRAM_RD_START_RD, 0);	//拉低读开始信号
}//===========================中断处理函数===========================//
void IntrHandler(void *CallbackRef)
{int r_data;xil_printf("Interrupt Detected , Start Read BRAM :\r\n");//clear interrupt status//PL_BRAM_RD_mWriteReg(PL_RAM_BASE, PL_RAM_CTRL , INTRCLR_MASK) ;//BRAM控制器读数据for(int i=0; i<wr_len*2; i++){//XBram_ReadReg(BRAM基地址,偏移量)//读写地址=基地址+偏移量r_data = XBram_ReadReg(BRAM_BASEADDR, i*BRAM_DATA_BYTE);xil_printf("Address:%d	Data:%c \r\n", i*BRAM_DATA_BYTE, r_data);}xil_printf("\r\n");
}//===========================建立中断系统===========================//
/* 建立中断系统,使能自定义IP核终端输出信号的上升沿产生中断* @param GicInstancePtr 是指向 XScuGic 驱动实例的指针* @param DeviceIntrID   是器件中断 ID*/
void Set_Intr_Sys(XScuGic *GicInstancePtr, u16 DeviceIntrID)
{//定义中断控制器配置信息(指针类型)XScuGic_Config * IntcConfig;//根据中断控制器ID,查找GIC配置信息(Generic Interrupt Controller(通用)中断控制器)IntcConfig = XScuGic_LookupConfig(INTC_DEVICE_ID);//初始化中断控制器驱动XScuGic_CfgInitialize(GicInstancePtr, IntcConfig, IntcConfig->CpuBaseAddress);//设置并打开中断异常处理功能Xil_ExceptionInit();Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,(Xil_ExceptionHandler)XScuGic_InterruptHandler,GicInstancePtr);//为GPIO中断设置中断处理函数(IntrHandler为自己编写的中断函数)XScuGic_Connect(GicInstancePtr, DeviceIntrID,(Xil_ExceptionHandler)IntrHandler, (void *) NULL); //自定义IP核无实例NULL//使能处理器中断Xil_ExceptionEnable();//设置中断优先级、触发类型(优先级从最高0开始步长8最大为248,0xA0=160优先级中等;触发类型:上升沿)XScuGic_SetPriorityTriggerType(GicInstancePtr, DeviceIntrID, 0xA0 , 0x3);//使能来自于器件的中断XScuGic_Enable(GicInstancePtr, DeviceIntrID);
}

相关文章:

ZYNQ笔记(十四):基于 BRAM 的 PS、PL 数据交互

版本&#xff1a;Vivado2020.2&#xff08;Vitis&#xff09; 实验任务&#xff1a; PS 将字符串数据写入BRAM&#xff0c;再将数据读取出来&#xff1b;PL 从 BRAM 中读取数据&#xff0c;bing。通过 ILA 来观察读出的数据&#xff0c;与前面串口打印的数据进行对照&#xff0…...

月之暗面开源 Kimi-Audio-7B-Instruct,同时支持语音识别和语音生成

我们向您介绍在音频理解、生成和对话方面表现出色的开源音频基础模型–Kimi-Audio。该资源库托管了 Kimi-Audio-7B-Instruct 的模型检查点。 Kimi-Audio 被设计为通用的音频基础模型&#xff0c;能够在单一的统一框架内处理各种音频处理任务。主要功能包括&#xff1a; 通用功…...

文件操作及读写-爪哇版

文章目录 前言 初识文件文件路径里的符号文件分类文件操作方法文件读写字节流输入输出输入输出 字符流输入输出输入输出 前言 Windows用户需知&#xff1a;“/”和“\”&#xff0c; 文件路径分隔符一般都用“/”&#xff0c;但Windows系统一直保留着“\”&#xff0c;这两种符…...

【matlab】绘制maxENT模型的ROC曲线和omission curve

文章目录 一、maxENT模型二、ROC曲线三、实操3.1 数据提取3.2 绘制ROC曲线3.3 绘制遗漏曲线3.4 多次训练的ROC和测试的ROC 一、maxENT模型 前面的文章已经详细讲过了。 maxENT软件运行后&#xff0c;会生成一个html报告&#xff0c;里面有ROC曲线&#xff0c;但我们往往需要自…...

个人电子白板(svg标签电子画板功能包含正方形、文本、橡皮 (颜色、尺寸、不透明度)、 撤销、取消撤销 等等功能,)

在Http开发中&#xff0c;svg标签电子画板功能包含正方形、文本、橡皮 &#xff08;颜色、尺寸、不透明度&#xff09;、 撤销、取消撤销 等等功能&#xff0c; 效果图 代码如下&#xff1a; <!DOCTYPE html> <html lang"en"> <!--<link href&qu…...

Pygame终极项目:从零开发一个完整2D游戏

Pygame终极项目:从零开发一个完整2D游戏 大家好!欢迎来到本期的Pygame教程。今天,我们将从零开始开发一个完整的2D游戏。通过这个项目,你将学习到如何使用Pygame库来创建游戏窗口、处理用户输入、绘制图形、管理游戏状态、实现碰撞检测和音效等。无论你是初学者还是有一定…...

在应用运维过程中,业务数据修改的证据留存和数据留存

在应用运维过程中,业务数据修改的证据留存和数据留存至关重要,以下是相关介绍: 一、证据留存 操作日志记录 : 详细记录每一次业务数据修改的操作日志,包括操作人员、操作时间、修改内容、修改前后数据的对比等。例如,某公司业务系统中,操作日志会精确记录员工小张在 2…...

JAVA JVM面试题

你的项目中遇到什么问题需要jvm调优&#xff0c;怎么调优的&#xff0c;堆的最小值和最大值设置为什么不设置成一样大&#xff1f; 在项目中&#xff0c;JVM调优通常源于以下典型问题及对应的调优思路&#xff0c;同时关于堆内存参数&#xff08;-Xms/-Xmx&#xff09;的设置逻…...

C盘爆红如何解决

deepseek来试用一下&#xff01; 一、快速释放空间 1. 清理临时文件 - **Win R** 输入 %temp% → 删除文件夹内所有内容。 - **Win S** 搜索 “磁盘清理”** → 选择C盘 → 勾选“临时文件”“系统缓存”等 → 点击“清理系统文件”&#xff08;可额外清理Windows…...

在 Ubuntu24.04 LTS 上 Docker 部署英文版 n8n 和 部署中文版 n8n-i18n-chinese

一、n8n 简介 n8n 是一个低代码&#xff08;Low-Code&#xff09;工作流自动化平台&#xff0c;可以帮助用户以非常简单的方式创建自动化流程&#xff0c;连接不同的应用程序和服务。n8n的设计理念是为了让复杂的工作流变得简单易用&#xff0c;同时也支持高度的自定义&#xf…...

软件设计案例分析学习笔记

1.软件设计师内容小考 一、单选题 1.(单选题&#xff0c;1.0 分) 下列内聚种类中&#xff0c;内聚程度最高的是 ( )。 A. 功能内聚 B. 逻辑内聚 C. 偶然内聚 D. 过程内聚 第 1 题&#xff1a; 答案&#xff1a;A 解析&#xff1a;功能内聚是指模块内所有元素共同完成一个功能&a…...

魔百盒CM311-3-YST代工-晨星MSO9385芯片-2+8G-免拆卡刷通刷固件包

魔百盒CM311-3-YST代工-晨星MSO9385芯片-28G-免拆卡刷通刷固件包 刷机前准备&#xff1a; 准备一个8G或一下容量的优盘将其格式化为fat32格式&#xff1b;&#xff08;切记不要用做过电脑系统的优盘&#xff0c;不然刷机直接变砖&#xff09;&#xff1b; 优盘卡刷强刷刷机&am…...

nginx 504 (Gateway Time-out)

目录 1. 后端处理超时 2. Nginx 代理超时设置不足 3. 服务未响应或崩溃 4. 请求体过大 5. 重启nginx 原本代理服务器用的是微软的Kestrel &#xff0c;今天给项目换用了nginx&#xff0c;然后有个接口请求报了 &#xff08;504 Gateway Timeout&#xff09; 请求发送到了…...

WPF 实现PLC数据采集

WPF 数据采集网关系统设计与实现 一、系统概述 本系统是一个基于 WPF 的数据采集网关,支持主流 PLC(可编程逻辑控制器)的数据采集,并将采集到的数据汇总存储到数据库中。系统采用模块化设计,具有良好的扩展性和可维护性。 二、系统架构 1. 整体架构 +---------------…...

llama factory怎么命令行推理图片

根据LLaMA-Factory多模态数据处理规范&#xff0c;配置图片输入需注意以下核心要点&#xff1a; --- **一、本地图片路径配置** 1. 绝对路径配置&#xff1a; json "images": ["/home/user/project/data/mllm_demo_data/1.jpg"] *适用场景*…...

计算机网络 | 应用层(1)--应用层协议原理

&#x1f493;个人主页&#xff1a;mooridy &#x1f493;专栏地址&#xff1a;《计算机网络&#xff1a;自定向下方法》 大纲式阅读笔记 关注我&#x1f339;&#xff0c;和我一起学习更多计算机的知识 &#x1f51d;&#x1f51d;&#x1f51d; 目录 1. 应用层协议原理 1.1 …...

刚体运动 (位置向量 - 旋转矩阵) 笔记 1.1~1.3 (台大机器人学-林沛群)

目录 1. 理解刚体的“自由度”&#xff08;Degrees of Freedom, DOF&#xff09; 1.1 平面运动 (2D) 1.2 空间运动 (3D) 2. 统一描述&#xff1a;引入“体坐标系”&#xff08;Body Frame&#xff09; 3. 从“状态”到“运动”&#xff1a;引入微分 3.1 补充&#xff1a;…...

MES系列-MOM(Manufacturing Operations Management,制造运营管理)

MES系列文章目录 ISA-95制造业中企业和控制系统的集成的国际标准-(1) ISA-95制造业中企业和控制系统的集成的国际标准-(2) ISA-95制造业中企业和控制系统的集成的国际标准-(3) ISA-95制造业中企业和控制系统的集成的国际标准-(4) ISA-95制造业中企业和控制系统的集成的国际标准…...

矩阵系统私信功能开发技术实践,支持OEM

在短视频矩阵系统中&#xff0c;私信功能是连接运营者与用户、用户与用户的重要桥梁。它不仅能提升用户粘性&#xff0c;还能为精准营销提供支持。本文将从需求分析、技术选型、核心功能实现到性能优化&#xff0c;全面解析矩阵系统私信功能的开发过程。 一、功能需求分析 &am…...

leetcode 26和80

leetcode 26. Remove Duplicates from Sorted Array 代码&#xff1a; class Solution { public:int removeDuplicates(vector<int>& nums) {int len nums.size();int slowIdx 1;for(int firstIdx 1; firstIdx < len;firstIdx){if(nums[firstIdx] ! nums[firs…...

微信小程序 template 模版详解

一、什么时候使用template &#xff1f; 代码复用&#xff0c;维护方便&#xff0c;提高性能 二、模版的基本使用 三、模版样式的使用 四、使用模版 五、使用模版定义的样式&#xff0c;需要在引入的wxml 样式文件中导入样式 六、template模版...扩展符数据传递 可以根据自己…...

北斗导航 | 基于Transformer+LSTM+激光雷达的接收机自主完好性监测算法研究

基于Transformer+LSTM+激光雷达的接收机自主完好性监测算法研究 接收机自主完好性监测(RAIM)是保障全球导航卫星系统(GNSS)定位可靠性的核心技术。传统RAIM算法依赖最小二乘残差法,存在故障漏检、对复杂环境适应性差等问题。结合Transformer、LSTM与激光雷达的多模态融合…...

ASP.NET CORE部署IIS的三种方式

ASP.NET Core 部署方式对比 本文档对比了三种常见的 ASP.NET Core 应用&#xff08;如你的 DingTalkApproval 项目&#xff09;部署到 Windows 10 上 IIS 服务器的方式&#xff1a;dotnet publish&#xff08;手动部署&#xff09;、Web Deploy&#xff08;直接发布到 IIS&…...

推荐三款GitHub上高星开源的音乐搜索平台

文章目录 一、Spottube 1. 展示 2. 功能 3. 安装 二、YesPlayMusic 1. 展示 2. 功能 2. 安装 三、Navidrome 1. 展示 2. 功能 3. 安装 一、Spottube 一个开源的跨平台 Spotify 客户端&#xff0c;兼容多个平台&#xff0c;利用 Spotify 的数据 API 和 YouTube、P…...

Linux基础指令【上】

Linux的基本操作 &#xff0c; 是通过指令来执行的&#xff01; 小贴士&#xff1a;指令很多&#xff0c;但一定要摒弃那种看到知识点就全部死记硬背的坏习惯&#xff08;因为就算背&#xff0c;也背不完&#xff09; &#xff0c; 一定要以理解为主&#xff0c;练习为辅 &…...

GPT系列模型-20250426

文章目录 🧠 GPT-4o(Omni)🔬 GPT-4.5(研究预览)🧩 o3 模型系列(o3、o3-mini、o3-mini-high)🧠 o4-mini 和 o4-mini-high🧠 GPT-4o mini🧾 总结对比表🧠 GPT-4o(Omni) 特点:全能型模型,支持文本、图像、音频和视频输入输出,具备强大的多模态处理能力。…...

高精度运算(string函数)

高精度加法 #include<iostream> #include<string> #include<algorithm> using namespace std; string _add(string s1,string s2); int main() {string a,b;cin>>a>>b;cout<<_add(a,b);return 0; } string _add(string s1,string s2) {re…...

探索 AI 在文化遗产保护中的新使命:数字化修复与传承

文化遗产是人类文明的瑰宝&#xff0c;承载着历史的记忆与文化的灵魂。然而&#xff0c;随着时间的推移和自然环境的影响&#xff0c;许多珍贵的文化遗产正面临着损毁和消失的威胁。在这样的背景下&#xff0c;人工智能&#xff08;AI&#xff09;技术的出现为文化遗产的保护和…...

Python----深度学习(基于DNN的PM2.5预测)

一、目标 如何使用 PyTorch 实现一个简单的深度神经网络&#xff08;DNN&#xff09;模型&#xff0c;并用于回归任务。该模型通过训练数据集来预测PM2.5。代码通过读取数据集、数据处理、模型训练和模型评估等步骤&#xff0c;详细展示了整个实现过程。 二、数据集介绍 Data …...

Android12源码编译及刷机

由于google的AOSP源码拉取经常失败&#xff0c;编译还经常出现各种问题。这里根据香橙派Orange Pi 5 Plus&#xff08;Android12电视镜像&#xff09;源码进行编译演示。 RK芯片的开发板可玩性很高&#xff0c;这里以电视版本android系统为例子&#xff0c;学习的同时还可以当…...

TRO再添新案 TME再拿下一热门IP,涉及Paddington多个商标

4月2日和4月8日&#xff0c;TME律所代理Paddington & Company Ltd.对热门IP Paddington Bear帕丁顿熊的多类商标发起维权&#xff0c;覆盖文具、家居用品、毛绒玩具、纺织用品、游戏、电影、咖啡、填充玩具等领域。跨境卖家需立即排查店铺内的相关产品&#xff01; 案件基…...

如何使用 Spring Boot 实现分页和排序:配置与实践指南

在现代 Web 应用开发中&#xff0c;分页和排序是处理大量数据时提升用户体验和系统性能的关键功能。Spring Boot 结合 Spring Data JPA 提供了简单而强大的工具&#xff0c;用于实现数据的分页查询和动态排序&#xff0c;广泛应用于 RESTful API、后台管理系统等场景。2025 年&…...

asammdf 库的信号处理和数据分析:深入挖掘测量数据

内容概要​​&#xff1a; 信号处理的基本操作数据分析和统计数据可视化和报告生成 ​​正文​​&#xff1a; 信号处理的基本操作 asammdf 提供了对信号的基本操作&#xff0c;包括读取、筛选和转换。 读取信号 with asammdf.MDF(nameexample.mf4) as mdf:engine_speed …...

在springboot项目中,如何进行excel表格的导入导出功能?

以下是使用 Apache POI 和 EasyExcel 实现 Excel 表格导入导出功能的具体代码示例。 1. 使用 Apache POI 实现 Excel 导入导出 添加依赖 在 pom.xml 中添加 Apache POI 的依赖&#xff1a; <dependency><groupId>org.apache.poi</groupId><artifactId…...

【C++11】右值引用和移动语义:万字总结

&#x1f4dd;前言&#xff1a; 这篇文章我们来讲讲右值引用和移动语义 &#x1f3ac;个人简介&#xff1a;努力学习ing &#x1f4cb;个人专栏&#xff1a;C学习笔记 &#x1f380;CSDN主页 愚润求学 &#x1f304;其他专栏&#xff1a;C语言入门基础&#xff0c;python入门基…...

29、简要描述三层架构开发模式以及三层架构有哪些好处?

三层架构开发模式概述 三层架构&#xff08;3-Tier Architecture&#xff09;是一种将软件系统按功能模块垂直拆分为三个独立逻辑层的经典设计模式&#xff0c;自20世纪90年代提出以来&#xff0c;已成为企业级应用开发的主流范式。其核心思想是通过职责分离和松耦合设计&…...

PotPlayer,强大的高清视频播放器

PotPlayer 是一款强大的的高清视频播放器&#xff0c;兼容多种音频和视频格式&#xff0c;支持多种硬件加速解码&#xff0c;包括DXVA、CUDA、QuickSync等。支持立体视频播放技术、字幕支持、截屏工具以及视频录制等多种功能。文末获取&#xff01; 1.鼠标右键【PotPlayer】压…...

AI数字人:未来职业的重塑(9/10)

摘要&#xff1a;AI 数字人凭借计算机视觉、自然语言处理与深度学习技术&#xff0c;从虚拟形象进化为智能交互个体&#xff0c;广泛渗透金融、教育、电商等多领域&#xff0c;重构职业生态。其通过降本提效、场景拓展与体验升级机制&#xff0c;替代重复岗位工作&#xff0c;催…...

Qt开发:如何加载样式文件

文章目录 一、加载图片资源二、QSS的使用介绍三、QSS的应用步骤与示例 一、加载图片资源 右键项目->选择"Add New…“之后&#xff0c;会弹出如下界面&#xff1a; 选择Qt->Qt Resource File即可。 点击下一步 点击上图中的LoadImageDemo.qrc文件&#xff0c;右…...

【10分钟读论文】Power Transmission Line Inspections电力视觉水文

标题Power Transmission Line Inspections: Methods, Challenges, Current Status and Usage of Unmanned Aerial Systems 2024 评分一颗星 论文《Power Transmission Line Inspections: Methods, Challenges, Current Status and Usage of Unmanned Aerial Systems》的核心内…...

[详细无套路]MDI Jade6.5安装包下载安装教程

目录 1. 软件包获取 2. 下载安装 3. 启动 4. 问题记录 写在前面: 垂死病中惊坐起,JAVA博主居然开始更博客了~ 最近忙项目了, 没啥更新的动力,见谅~见谅~. 这次博主的化工友友突然让帮安装JADE6.5软件,本来以为不就一个软件,直接拿捏. 不料竟然翻了个小车, 反被拿捏了. 既…...

Spring Boot 参考文档导航手册

&#x1f4da; Spring Boot 参考文档导航手册 &#x1f5fa;️ ✨ 新手入门 &#x1f476; 1️⃣ &#x1f4d6; 基础入门&#xff1a;概述文档 | 环境要求 | 安装指南 2️⃣ &#x1f527; 实操教程&#xff1a;上篇 | 下篇 3️⃣ &#x1f680; 示例运行&#xff1a;基础篇 …...

多个请求并行改造

改成 compose 页面的recompose次数 有时候recompose次数没必要优化&#xff0c;除非真的影响到性能了...

前端与Rust后端交互:跨越语言鸿沟 (入门系列三)

作为前端开发者&#xff0c;在Tauri应用中与Rust后端交互可能是最陌生的部分。本文将帮助你理解这一过程&#xff0c;无需深入学习Rust即可实现高效的前后端通信。 极简上手项目 apkParse-tauri 命令系统&#xff1a;前端调用Rust函数 Tauri的核心通信机制是"命令系统&q…...

ClickHouse查询执行与优化

SQL语法扩展与执行计划分析 特殊函数与子句 WITH子句&#xff1a;定义临时表达式&#xff08;CTE&#xff09;&#xff0c;复用中间结果。 WITH tmp AS (SELECT ...) SELECT * FROM tmp ANY修饰符&#xff1a;在JOIN时仅保留第一个匹配的行&#xff08;避免笛卡尔积爆炸&…...

[Kaggle]:使用Kaggle服务器训练YOLOv5模型 (白嫖服务器)

【核知坊】&#xff1a;释放青春想象&#xff0c;码动全新视野。 我们希望使用精简的信息传达知识的骨架&#xff0c;启发创造者开启创造之路&#xff01;&#xff01;&#xff01; 内容摘要&#xff1a;最近需要使用 YOLOv5 框架训练一个识别模型&#xf…...

Debian安装避坑

Debian安装避坑 不要联网安装不支持root直接登陆默认没有ssh服务默认没有sudo命令 不要联网安装 安装系统的时候不要联网安装, 直接关闭网卡 否则在线下载最新的包非常耗时间. 不支持root直接登陆 ssh <创建的普通用户名>机器ip默认没有ssh服务 # 安装ssh服务 apt ins…...

Android Gradle插件开发

文章目录 1. Gradle插件是什么2. 为什么需要插件3. 编写插件位置4. 编写插件5. 自定义插件扩展5.1 订阅扩展对象5.2 把扩展添加给Plugin并使用5.3 配置参数5.4 嵌套扩展5.4.1 定义扩展5.4.2 获取扩展属性5.4.3 使用5.4.4 执行5.4.5 输出 6. 编写在单独项目里6.1 新建Module6.2 …...

goweb项目结构以及如何实现前后端交互

项目结构 HTML模板 使用ParseFiles可以解析多个模板文件 func ParseFiles(filenames ...string)(*Teplate,error){return parseFiles(nil,filenames...) }把模板信息响应写入到输入流中 func (t *Template) Exwcute(wr io.Writer,data interface{})error{if err:t.escape();…...

Astro canvas大屏从iotDA上抽取设备影子的参数的详细操作实施路径

目录 &#x1f6e0; 场景&#xff1a; &#x1f3af; 核心思路 &#x1f5fa; 详细操作实施路径&#xff08;针对小白版&#xff09; &#x1f69b; 第1步&#xff1a;配置桥接器&#xff08;建立连接通道&#xff09; &#x1f4cb; 第2步&#xff1a;配置数据集&#xf…...