【正点原子FPGA连载】第二十二章IP封装与接口定义实验 摘自【正点原子】DFZU2EG_4EV MPSoC之嵌入式Vitis开发指南
1)实验平台:正点原子MPSoC开发板
2)平台购买地址:https://detail.tmall.com/item.htm?id=692450874670
3)全套实验源码+手册+视频下载地址: http://www.openedv.com/thread-340252-1-1.html
第二十二章IP封装与接口定义实验
在前面的实验中,我们通过调用各种功能的IP核,可以快速地搭建Block Design。除了调用Vivado IP库中的IP核,我们还可以创建或封装自己的IP核。在本章我们将学习如何把HDL实现的功能模块封装成IP核,以及如何定义新的接口类型。
本章包括以下几个部分:
2222.1简介
22.2实验任务
22.3硬件设计
22.4程序设计
22.5下载验证
22.1简介
Vivado开发工具集成了大量Xilinx官方IP核以及第三方厂商提供的IP核,如图 22.1.1所示。这些IP核可以实现不同类型的功能,通过调用IP核可以大大加速我们的设计流程。我们也可以创建或封装自己的IP核,并将之添加到Vivado的IP库中,以方便模块的重复调用,或者在团队开发过程中进行IP的共用。

图 22.1.1 Vivado IP核目录
在搭建Block Design的过程中,我们通过连线将各IP核相同类型的接口连接起来。IP核通过接口与外部模块进行信号传递,在Vivado的IP库中包含各种不同类型的接口定义,如图 22.1.2所示:

图 22.1.2 Vivado 接口目录
IP核的接口(Interfaces)由一个或者多个端口(Ports)组成,不同类型的信号需要通过不同类型的接口进行传递。需要注意的是,这里的“信号”可以由一根信号线传递,如时钟信号,此时时钟接口仅包含一个端口。有的信号需要通过多根信号线进行传递,比如视频信号,它包含像素数据、行同步信号和场同步信号等,那么视频接口就由多个端口组成,各个端口分别由独立的信号线连接。
例如,图 22.1.3是AXI GPIO IP核的模块框图,从图中可以看出该IP核有四个接口。其中由两个红色箭头指示的加号表示这两个接口由多个端口组成,另外两个接口则只包含一个端口。

图 22.1.3 AXI GPIO IP核
我们点击上图中红色箭头所指示的加号可以将该接口展开,如下图所示:

图 22.1.4 接口与端口
从图 22.1.4中可以看出,S_AXI接口共包含17个端口,端口名均以s_axi_开头。GPIO接口共包含3个端口,端口名均以gpio_io_开头。
在创建自定义IP核的过程中,为了方便IP核之间的信号连接,我们可以把模块中同类性质或者属于同一组信号的多个端口定义成一个接口。如果在Vivado的IP库中找不到所需要的接口类型,我们也可以重新创建一个新的接口定义。
22.2实验任务
本章的实验任务是将“HDMI彩条显示实验”中所实现的RGB2DVI模块封装成一个IP核。
22.3硬件设计
本次实验中的硬件设计部分与“HDMI彩条显示实验”完全相同,请大家参考《MPSOC之FPGA开发指南》中相应的章节。
22.4程序设计
(1)创建IP目录
首先我们在Vivado工程目录下新建一个文件夹DVI_TX,这个就是我们要封装的IP所在的位置。这个目录可以与大家平时创建Vivado工程的路径一致,也可以选择其他路径,但是要求路径名只能由英文字母、数字和下划线组成,不能包含中文、空格或者特殊字符。
接下来,在DVI_TX文件夹中另外新建两个文件夹:ip和if。其中ip用于存放封装的IP核,if用于存放我们定义的接口(if是interface的缩写)。创建完成后如下图所示:

图 22.4.1 IP核与接口文件目录
然后在ip文件夹中新建一个名为src的文件夹,并将HDMI彩条显示实验中RGB2DVI模块所对应的4个源文件拷贝到src文件夹中,拷贝完成后如下图所示:

图 22.4.2 IP封装使用的模块源文件
为了方便大家能够快速地找到这几个源文件,在这里我们也把这几个源文件所在的位置截图如下:

图 22.4.3 HDMI彩条显示实验源文件
(2)创建Vivado工程
在文件夹目录和源文件准备好之后,接下来我们需要创建一个Vivado工程,用于管理IP核。
首先打开Vivado软件,软件启动后在Tasks一栏选择“Manage IP”,然后点击“New IP Location”,如下图所示:

图 22.4.4 新建IP路径
在弹出的对话框中点击“Next”,如下图所示:

图 22.4.5 创建自定义 IP路径向导
在IP设置界面选择器件类型,并指定工程所在目录,然后点击“Finish”,如下图所示:

图 22.4.6 管理IP工程设置
需要注意的是,在图 22.4.6中,IP location一栏中的路径是Vivado工程所在的路径,与我们要封装的IP核所在的路径(即前面我们新建的DVI_TX文件夹)无关。
在上图中点击“Finish”之后,Vivado会新建一个名为“Manage IP”的工程,如下图所示:

图 22.4.7 Manage IP工程
(3)创建和封装IP
接下来,我们将在当前工程中创建和封装新的IP核。
在菜单栏中点击“Tools”,然后在下拉列表中选择“Create and Package New IP”,如下图所示:

图 22.4.8 创建和封装IP
在弹出的对话框中点击“Next”,如下图所示:

图 22.4.9 创建和封装IP
然后在下一个界面中选择“Package a specified directory”,然后点击“Next”,如下图所示:

图 22.4.10 选择封装一个指定的目录
在下图所示界面中,指定要封装的IP核源文件所在的目录,即我们前面所创建的DVI_TX文件夹中的ip目录,源文件位于该目录下的src文件夹内。然后点击Next,如下图所示:

图 22.4.11 选择源文件所在目录
在下一个界面中提示将会重新打开一个工程,我们将在新建的工程中对IP核进行编辑。工程的名称和路径已经自动添加,我们直接点击Next,如下图所示:

图 22.4.12 IP封装工程名
最后点击Finish,如下图所示:

图 22.4.13 新IP创建
在点击Finish之后,Vivado会重新打开一个工程用于编辑IP核,如下图所示:

图 22.4.14 编辑IP工程
在图 22.4.14中我们可以在Sources栏看到需要进行封装的IP核源文件。需要注意的是,箭头指示的模块serializer_10_to_1前有品字形的标识,表明该模块被识别成顶层模块。但是顶层模块实际上是dvi_transmitter_top模块,因此我们需要在dvi_transmitter_top上右击,然后选择“Set as top”,将其设置成顶层模块,如下图所示:

图 22.4.15 设置顶层模块
在修改顶层模块之后,接下来我们要对IP核进行设置和编辑。
(4)设置IP信息
在主界面Package IP页中,点击左侧Packaging Steps一栏中的“Identification”。然后修改右侧箭头所指示的选项,括厂商(Vendor)、IP核名称(Name)、IP核显示名称(Display name)以及对IP核的描述(Description)等信息。修改后的IP核信息如下图所示:

图 22.4.16 IP核信息
从图 22.4.16下方红色方框所标识的内容可以看出,IP核的根目录位于DVI_TX/ip文件夹中。
(5)设置IP兼容性
然后点击左侧Packaging Steps一栏中的“Compatibility”,在右侧设置IP核兼容性,如下图所示:

图 22.4.17 IP核兼容性
IP核兼容性是指我们封装的IP核可用于哪些型号的器件。由于我们封装的RGB2DVI模块在设计时用到了器件的原语,其功能与器件底层的硬件结构有一定的关联,因此并不适用于Xilinx所有型号的器件。此处我们在IP核兼容性中只保留zynqplus系列。然后将其他所有型号的器件选中后,点击图 22.4.17中箭头所指示的减号将其删除。
在删除多余的器件型号后,IP核兼容性设置如下图所示:

图 22.4.18 IP核兼容性设置
(6)设置文件组
然后点击左侧Packaging Steps一栏中的“File Groups”,如下图所示:

图 22.4.19 IP核文件组
在文件组(File Groups)中列出了IP核所使用到的源文件。由于我们前面修改了顶层模块,因此在图 22.4.19中我们需要点击箭头所指示的位置,将改动更新到文件组向导界面。
(7)设置变量
接下来点击左侧Packaging Steps一栏中的“Customization Parameters”如下图所示:

图 22.4.20 IP核定制变量
这里我们同样需要点击图 22.4.20中红色箭头所指示的位置,将改动更新到定制变量(Customization Parameters)向导界面中。在点击之后会弹出对话框提示出现错误,如下图所示:

图 22.4.21 错误提示
这个错误是由于工具最开始错误地识别了顶层模块,这个错误我们将会稍后解决,在这里我们直接点击OK。
由于在RGB2DVI模块中没有定义parameter变量,因此在Customization Parameters页面工具没有识别到任何变量。
(8)设置端口和接口
接下来点击左侧Packaging Steps一栏中的“Ports and Interfaces”,如下图所示:

图 22.4.22 IP核端口和接口
我们将在图 22.4.22所示的界面设置IP核的端口和接口。在该界面中已经列出了顶层模块所有的输入和输出端口,同时工具自动识别出了reset_n等接口。但是工具自动识别出来的接口并不完全正确,需要我们根据各端口的定义重新进行修改。
在这里我们重新给出顶层模块的输入和输出接口定义,代码如下所示:
1 module dvi_transmitter_top(
2 input pclk, // pixel_clk
3 input pixel_clk_5x, // pixel_clk的5倍时钟
4 input pixel_clk_2_5x, // pixel_clk的2.5倍时钟
5 input reset_n, // reset
6
7 input [23:0] video_din, // RGB888 video in
8 input video_hsync, // hsync data
9 input video_vsync, // vsync data
10 input video_de, // data enable
11
12 output tmds_clk_p, // TMDS 时钟通道
13 output tmds_clk_n,
14 output [2:0] tmds_data_p, // TMDS 数据通道
15 output [2:0] tmds_data_n,
16 output tmds_oen // TMDS 输出使能
17 );
我们将代码中的接口与图 22.4.22中的接口进行对比发现,图 22.4.22中箭头所指示的两个接口信号在代码中并不存在。这同样是由于工具最开始将serializer_10_to_1模块识别成了顶层模块,而箭头所指示的两个接口信号正是serializer_10_to_1模块中的接口,因此我们需要先将这两个多余的接口从IP中移除。
选中多余的两个接口reset和paralell_clk,然后右击,选择“Remove Interface”,如下图所示:

图 22.4.23 移除多余接口
在移除这两个接口之后,图 22.4.23红色圆圈所指示的两个错误也随之消失。如下图所示:

图 22.4.24 错误提示消失
另外工具错误地将tmds_clk_n和tmds_clk_p这两个端口识别成了两个时钟接口,因此我们需要将这两个接口移除,如下图所示:

图 22.4.25 移除错误接口
移除错误的时钟接口后,IP核端口与接口界面如下图所示:

图 22.4.26 IP核端口与接口
如图 22.4.26中的红色方框所示,我们将该IP核的输入输出端口分成了四种接口类型:复位接口、时钟接口、视频接口和TMDS接口。其中复位接口已经由工具识别到复位信号reset_n后自动创建,而其他三个类型的接口需要我们手动添加。除此之外,由于TMDS连接中仅包含三个数据通道和一个时钟通道(详见HDMI彩条显示实验),因此tmds_oen信号没有划分到TMDS接口中,而是作为IP核独立的端口。
接下来我们首先添加时钟接口,由于每个时钟接口只包含一路时钟信号,因此我们需要为pclk、pclk_x5和pclk_x2_5各添加一个时钟接口。
(9)添加时钟接口
在pclk上右击,然后选择“Add Bus Interface”,如下图所示:

图 22.4.27 添加总线接口
在弹出的对话框中选择General页面。首先要指定添加的接口类型,默认的接口类型是aximm_rtl,如下图所示:

图 22.4.28 添加接口
点击图 22.4.28中箭头所指示的按钮,然后在弹出的接口选择界面中点击放大镜图标进行搜索,如下图所示:

图 22.4.29 选择接口类型
由于我们需要添加时钟接口,因此在图 22.4.29的搜索栏中输入“clock”进行搜索。然后在下面列出的搜索结果中选择clock_rtl,在其右侧可以看到对该接口的描述“Xilinx时钟信号接口”,最后点击“OK”。
在返回General界面后,输入该时钟接口的名称为pclk,并设置模式为slave。如下图所示:

图 22.4.30 指定接口名称与模式
当模式设置为slave时,表示该时钟接口是一个输入接口;如果设置为master,则表示它是一个输出接口。在RGB2DVI模块中,两个时钟信号均为输入信号,因此需要设置为slave。
接下来我们进入Port Mapping页面,将接口的逻辑端口与IP的物理端口映射起来,如下图所示:

图 22.4.31 IP端口映射
在图 22.4.31中,左侧的Interface’s Logical Ports指的是我们添加的接口由哪些端口组成,比如时钟接口就只有一个名为“CLK”的时钟端口。而在右侧的IP’s Physical Ports一栏中列出了IP核顶层模块所有的输入输出端口。我们需要在Port Mapping页面中将二者映射起来,也就是为我们模块的输入输出端口指定信号类型。
如图 22.4.31中的两个圆圈所示,在左侧点击选中逻辑端口CLK,然后在右侧选中物理端口pclk,最后点击箭头所指示的按钮“Map Ports”即可完成pclk的端口映射。映射之后的端口会在下方Mapped Ports Summary栏中列出。
最后点击右下角的OK,即可完成时钟接口的添加,添加完成后如下图所示:

图 22.4.32 添加pclk时钟接口
图 22.4.32中箭头所指示的是我们为IP核手动添加的时钟接口,并将其命名为pclk。该时钟接口只包含一个端口,即顶层模块的输入端口pclk。
IP核顶层模块有三个输入时钟,因此我们需要为pclk_x5和pclk_x2_5分别添加一个时钟接口。该过程与添加pclk时钟接口的步骤是相同的,只需要在接口命名时分别修改为pclk_x5和pclk_x2_5。添加完成之后如下图所示:

图 22.4.33 添加pclk_x5和pclk_x2_5时钟接口
(10)添加视频接口
在添加了三个时钟接口之后,接下来我们要为图 22.4.33中红色方框标注的四个端口添加一个视频接口。在其中任一端口上右击,然后选择“Add Bus Interface”。
在弹出的对话框中选择General页面,然后点击“Interface Definition”右侧的按钮选择接口类型。
接下来,在接口选择界面搜索“video”,然后选择“vid_io_rtl”视频接口,如下图所示:

图 22.4.34 选择视频接口
在图 22.4.34中点击右下角的“OK”返回General界面,然后输入接口名称“Video_In”。另外,将该视频接口的模式设置为“Slave”,即作为输入接口,如下图所示:

图 22.4.35 设置视频接口
在图 22.4.35中“Description”一栏输入对该视频接口的描述RGB888 Video,表明输入的视频数据格式为RGB888。
接下来在Port Mapping界面对端口进行映射,如下图所示:

图 22.4.36 视频端口映射
从图 22.4.36中可以看出,我们所添加的视频接口共包含7个端口,但是我们只用到了其中四个:DATA是视频像素数据,ACTIVE_VIDEO是视频有效信号,HSYNC和VSYNC分别是视频的行同步和场同步信号。
我们按照图中箭头所指示的连接方式将上述四个端口与IP核的视频端口一一映射起来,映射完成后的端口在下方Mapped Ports Summary栏中列出。
最后点击右下角的OK,完成视频接口的添加。添加完成后IP核接口页面如下图所示:

图 22.4.37 添加Video_In视频接口
到这里我们已经成功添加了时钟接口和视频接口,接下来我们要为图 22.4.37中圆圈所标注的四个端口添加一个TMDS接口。但是在Vivado的IP库中并没有这个TMDS的接口定义,因此我们需要先定义一个TMDS接口。
(11)创建TMDS接口定义
在当前工程中的菜单栏点击“Tools”,然后选择“Create Interface Definition”,如下图所示:

图 22.4.38 创建接口定义
在弹出的对话框中选择“Create new interface definition”,然后分别输入厂商(Vendor)、接口名(Name)、路径(Location)等信息,如下图所示

图 22.4.39 设置接口定义
在图 22.4.39中将接口名称设置为“TMDS”,路径设置为IP核路径中的if文件夹,然后点击OK。
接下来工具会自动打开TMDS接口的配置界面,里面已经包含了前面设置的接口信息,如下图所示:

图 22.4.40 添加TMDS接口端口
在图 22.4.40中的Description一栏,我们可以添加对该接口的描述——“TMDS Link Interface”,即TMDS连接接口。TMDS接口一共包含四个端口,分别是:tmds_clk_p、tmds_clk_n、tmds_data_p和tmds_data_n,其中tmds_data_p和tmds_data_n的位宽为3位。
接下来我们需要为该接口添加端口,在上图中Ports一栏点击箭头所指示的加号,会弹出如下图所示的对话框:

图 22.4.41 设置端口
如图 22.4.41所示,我们添加的第一个端口名为“tmds_clk_p”,并将其默认值(Default Value)设置为0。接下来我们还需要针对TMDS接口的Master和Slave两种模式,分别设置该端口的属性。首先在这两种模式下该端口的位宽(Width)都是1位,另外在Master模式下该端口作为输出信号(out),在Slave模式下该端口作为输入信号(in)。
接下来在端口类型(Type)一栏,勾选“Clock”一项,表明该端口传输的是时钟信号。最后点击右下角的OK。
端口属性设置完成后TMDS接口定义界面如下图所示:

图 22.4.42 添加tmds_clk_p端口
然后我们还需要按照同样的方式添加tmds_clk_n端口,在这里就不再赘述了。
接下来我们添加tmds_data_p端口,tmds_data_p端口的设置界面如下图所示:

图 22.4.43 设置tmds_data_p端口
需要注意的是图 22.4.43中圆圈标注的部分,与tmds_clk_p端口不同,tmds_data_p端口的位宽(Width)为3,类型(Type)为数据(Data)。然后我们需要按照同样的方式tmds_data_n端口。
所有的端口添加完成后TMDS接口定义的界面如下图所示:

图 22.4.44 TMDS接口定义
到这里我们的TMDS接口就创建完成了,点击图 22.4.44中右下角的Save保存。
保存后我们可以到最开始创建的DVI/if文件夹下查看所生成的接口定义文件,如下图所示:

图 22.4.45 TMDS接口定义文件
在创建TMDS接口定义之后,我们在IP核中添加该接口。
(12)添加TMDS接口
在图 22.4.37中圆圈所标注出的端口上右击,然后选择“Add Bus Interface”,然后在弹出的接口选择界面搜索“TMDS”,如下图所示:

图 22.4.46 添加TMDS接口
在图 22.4.46中可以看到,TMDS_rtl接口所在的库为User,即用户自定义的接口。这个接口原本在Vivado的接口库中是不存在的,在我们创建其接口定义之后才能够搜索到。点击选中该接口后点击右下角的OK。
在返回General页面后,在该界面对添加的TMDS接口进行设置,如下图所示:

图 22.4.47 设置TMDS接口
图 22.4.47中,我们设置接口名为“TMDS”,然后设置模式为“master”,即该接口在IP核中作为输出接口。
设置完成后,我们到Port Mapping界面中对接口的端口进行映射,如下图所示:

图 22.4.48 TMDS接口端口映射
按照图 22.4.48中箭头所指示的连接方式,将左侧TMDS接口的逻辑端口与IP核的物理端口映射起来。映射后的端口会在下方Mapped Ports Summary一栏中列出。映射完成后点击图中右下角的OK。
至此,我们要封装的IP核所有的接口均已添加完成,如图 22.4.49所示。IP核共包括六个接口:Video_In、TMDS、reset_n、pclk、pclk_x5和pclk_x2_5。其中reset_n接口是工具在识别到模块的复位端口后自动添加的接口,而TMDS接口是我们自定义的接口。
另外,图中箭头所指示的tmds_oen端口将作为独立的端口存在,我们没有为它再创建新的接口定义。也就是说,在IP核中,并不是所有的端口都要以接口的形式存在。我们为IP核添加或者创建接口是为了更方便地连接IP核之间的端口信号。

图 22.4.49 IP核接口
(13)编辑复位接口
除了删除或者添加接口,我们还可以对IP核的接口重新进行编辑或者修改。在复位接口reset_n上右击,然后选择“Edit Interface”,如下图所示:

图 22.4.50 编辑接口
然后在弹出的窗口中进入“Parameters”页面,在该页面中可以为接口添加变量。如下图所示:

图 22.4.51 添加变量
在图 22.4.51左侧选择“POLARITY”变量,然后点击图中圆圈所标注的箭头,将该变量添加到右侧IP核的变量列表中。添加完成后如下图所示:

图 22.4.52 设置变量
在图 22.4.52中,我们需要在Value一栏设置POLARITY变量的值为ACTIVE_LOW。变量POLARITY指的是复位接口的极性,而我们将它的值设置为“ACTIVE_LOW”则表明该复位接口是低电平有效。这一设置需要与IP核程序设计中复位接口的极性保持一致。最后点击右下角的OK完成对复位接口的编辑。
到这里我们对IP核端口和接口的设置就完成了,其中时钟和复位接口会被折叠到“Clock and Reset Signals”分组中,如下图所示:

图 22.4.53 完成端口和接口设置
(14)查看IP核GUI界面
另外在我们封装的IP核中不涉及存储映射和地址空间等,因此可以直接跳过图 22.4.53中箭头所指示的Addressing and Memory设置界面,直接进入下一个Customization GUI界面。如下图所示:

图 22.4.54 IP核图形用户界面
在图 22.4.54中我们可以看到IP核封装后的图形用户界面,共包含五个接口和一个端口(tmds_oen)。
(15)封装IP核
最后我们点击左侧“Packaging Steps”一栏中的“Review and Package”,如下图所示:

图 22.4.55 封装IP
在图 22.4.55中的Summary一栏我们可以看到IP核的名称、描述,以及根目录等信息。确认无误后,点击下方的“Package IP”按钮完成IP封装。
IP封装完成后,会弹出一个对话框提示名为“DVI_Transmitter”的IP核封装成功,如下图所示:

图 22.4.56 关闭编辑IP工程
在对话框中给出了最终封装的IP所在的路径,并提示是否关闭当前工程,我们直接点击Yes。
接下来我们到IP核所在的路径中查看封装之后的IP核文件,如下图所示:

图 22.4.57 封装之后的IP
然后我们双击打开图 22.4.57中的xgui文件夹,如下图所示:

图 22.4.58 xgui文件夹
可以看到xgui文件夹中有两个文件,其中DVI_Transmitter_v1_0.tcl与我们封装的IP核名称一致。而另外一个名为serializer_10_to_1_v1_0.tcl的文件是由于工具最开始将serializer_10_to_1模块错误地识别成了顶层模块而生成的,在这里我们将图 22.4.58中箭头所指示的文件删除。
到这里我们的IP封装和接口定义就完成了,如下图所示:

图22.4.59 封装完成的IP
22.5下载验证
为了验证我们封装的IP核功能是否正常,我们可以将DVI_TX文件夹拷贝到《SD卡读BMP图片HDMI显示实验》的工程目录中,然后打开工程,将Block Design中的DVI_Transmitter模块替换成大家自己封装的IP。在重新编译之后,参考《SD卡读BMP图片HDMI显示实验》下载验证部分的操作方式进行下载。如果HDMI显示器上能够正常显示图像,即说明我们本次实验成功地完成了DVI_Transmitter IP核的封装和TMDS接口的定义。
相关文章:
【正点原子FPGA连载】第二十二章IP封装与接口定义实验 摘自【正点原子】DFZU2EG_4EV MPSoC之嵌入式Vitis开发指南
1)实验平台:正点原子MPSoC开发板 2)平台购买地址:https://detail.tmall.com/item.htm?id692450874670 3)全套实验源码手册视频下载地址: http://www.openedv.com/thread-340252-1-1.html 第二十二章IP封装…...
【ElasticSearch8.X】学习笔记(二)
【ElasticSearch8.X】学习笔记四、基础操作4.1、索引操作4.1.1、创建索引4.1.2、查询指定索引4.1.3、查询所有索引4.1.4、 删除索引4.2、文档操作4.2.1、创建文档4.2.2、查询文档4.2.3、修改文档4.2.4、删除文档4.2.5、查询所有文档4.3、数据搜索4.3.1、匹配查询文档4.3.2、匹配…...
Ubuntu22.04安装、配置、美化、软件安装、配置开发环境
Ubuntu22.04安装、配置、美化、软件安装、配置开发环境 一、Ubuntu、Windows11(10)双系统安装 因为ubuntu的安装网上的教程特别多了,所以这里不做赘述,推荐使用小破站这个up主的教程:Windows 和 Ubuntu 双系统从安装到…...
企业电子招投标采购系统之系统的首页设计
功能模块: 待办消息,招标公告,中标公告,信息发布 描述: 全过程数字化采购管理,打造从供应商管理到采购招投标、采购合同、采购执行的全过程数字化管理。通供应商门户具备内外协同的能力,为…...
Python爬虫-阿里翻译_csrf
前言 本文是该专栏的第37篇,后面会持续分享python爬虫干货知识,记得关注。 笔者在前面有介绍过百度翻译的案例,感兴趣的同学,可往前翻阅查看(JS逆向-百度翻译sign)。而本文,笔者要介绍的是阿里翻译,相对于百度翻译的参数被逆向需要花点时间,阿里相对于易上手。 下面…...
C语言实现三子棋【详解+全部源码】
大家好,我是你们熟悉的恒川 今天我们用C语言来实现三子棋 实现的过程很难,但我们一定要不放弃 三子棋1. 配置运行环境2. 三子棋游戏的初步实现2.1 建立三子棋分布模块2.2 创建一个名为board的二维数组并进行初始化2.3 搭建棋盘3. 接下来该讨论的事情3.1 …...
双指针法将时间复杂度从 O(n^2) 优化到 O(n)
[1] 什么是双指针法 双指针法(Two Pointers)是一种常见的算法技巧,常用于数组和链表等数据结构中。 双指针法的基本思想是维护两个指针,分别指向不同的位置,通过它们的移动来解决问题。在某些情况下,使用双…...
【SpringBoot系列】 Spring中自定义Session管理,Spring Session源码解析
系列文章:Spring Boot学习大纲,可以留言自己想了解的技术点 目录 系列文章:Spring Boot学习大纲,可以留言自己想了解的技术...
【上位机入门常见问题】SQLServer2019 安装指导
SQLServer2019 安装指导 这里要说一下SQLServer的版本问题,首先说纵向的高低版本,如果大家跟我学习,我教给大家的是T-SQL编程的方法,而不是直接操作菜单的方法,所以,我们学习中只要使用SQLServer2012或以上…...
RabbitMQ第一讲
目录 一、RabbitMQ-01 1.1 MQ概述 1.2 MQ的优势和劣势 1.2.1 优势 1.2.2 劣势 1.2.3 MQ应用场景 1.2.4 常用的MQ产品 1.3 RabbitMQ的基本介绍 1.3.1 AMQP介绍 1.3.2 RabbitMQ基础架构 1.3.3 RabbitMQ的6种工作模式 编辑 1.4 AMQP和JMS 1.4.1 AMQP 1.4.2 JMS …...
华为机试题:HJ100 等差数列(python)
文章目录(1)题目描述(2)Python3实现(3)知识点详解1、input():获取控制台(任意形式)的输入。输出均为字符串类型。1.1、input() 与 list(input()) 的区别、及其相互转换方…...
数据推荐 | 人体行为识别数据集
人体行为识别任务旨在通过对人体姿态进行分析,识别出人体的具体动作,为人体行为预测、突发事件处理、智能健身、智能看护等领域提供技术支持。 图片 图片 人体行为识别数据标注方式 人体行为数据通用的标注方式包括人体关键点标注和动作标签标注&#…...
667真题分析 | 2023年667真题简要分析和答题思路参考
2023年667真题简要分析和答题思路参考 文章目录 2023年667真题简要分析和答题思路参考前言1. 名词解释2. 简答题3. 分析题3.1 答题框架(套路)3.2 答题框架实战3.2.1 图书情报档案事业如何在文化自信、文化强国中发挥自己的地位和作用3.2.2 高校图书馆如何发挥空间资源的功能和…...
配置 Docker 使用 GPU
准备工作 首先你需要准备一台拥有GPU的实例,在这里我将使用阿里云的竞价实例来做演示,因为它对于短期使用GPU更加划算。 注意,本篇文章将教你手动进行GPU驱动的配置,所以在购买时选择系统的时候不要选择自动安装GPU驱动。 具体关…...
「并发编程实战」常见的限流方案
「并发编程实战」常见的限流方案 文章目录「并发编程实战」常见的限流方案一、概述二、计数器限流方案三、时间窗口限流方案四、令牌桶限流方案五、漏桶限流方案六、高并发限流算法小结文章参考: 追忆四年前:一段关于我被外企CTO用登录注册吊打的不堪往事…...
IO 复习
IO 把电脑硬盘中的数据读到程序中,称为输入,进行数据的read操作 把程序往外部设备写数据,称为输出,进行数据的write操作 File类 一个File对象可以表示计算机硬盘上的一个文件或目录(文件夹) 可以获取文件信息,创建文件,删除文件 但是不能对文件中的数据进行读写操作 一些…...
什么是项目管理
项目管理(简称PM),就是将知识、技能、工具与技术应用于项目活动,以满足项目的要求。项目管理通过合理运用与整合特定项目所需的项目管理过程得以实现。项目管理使组织能够有效且高效地开展项目 “现代管理,项目就是一切…...
什么是入站营销?如何向合适的受众推销
没有什么比入站营销更有效地优先考虑客户体验了。 入站营销可为您的客户在他们需要的时间和地点准确提供他们想要的东西。它以最有机的方式在您的行业中建立信任、忠诚和权威。 什么是入站营销? 入站营销是一种商业方法,可提供优质内容和量身定制的客户…...
Qt 崩溃 corrupted double-linked list Aborted
文章目录摘要1 使用全局静态变量2 不取第一个和最后一个数3 将数据计算放到同一线程计算4 替换槽函数5 修改传值为const6 神奇的环境因素7 更神奇的板子差异8 另一个细节Aborted最后关键字: Qt、 Aborted、 corrupted、 double、 linked 摘要 额,结论&…...
牛逼了!这是什么神仙面试宝典?半月看完25大专题,居然斩获阿里P7offer
这是什么神仙面试宝典?半月看完25大专题,居然斩获阿里P7offer???????容我小小的嘚瑟一下下啦~~这份神仙面试宝典总共有25大专题:专题一:JavaOOP面…...
PPT|230页| 制造集团企业供应链端到端的数字化解决方案:从需求到结算的全链路业务闭环构建
制造业采购供应链管理是企业运营的核心环节,供应链协同管理在供应链上下游企业之间建立紧密的合作关系,通过信息共享、资源整合、业务协同等方式,实现供应链的全面管理和优化,提高供应链的效率和透明度,降低供应链的成…...
oracle与MySQL数据库之间数据同步的技术要点
Oracle与MySQL数据库之间的数据同步是一个涉及多个技术要点的复杂任务。由于Oracle和MySQL的架构差异,它们的数据同步要求既要保持数据的准确性和一致性,又要处理好性能问题。以下是一些主要的技术要点: 数据结构差异 数据类型差异ÿ…...
C# 类和继承(抽象类)
抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...
JVM暂停(Stop-The-World,STW)的原因分类及对应排查方案
JVM暂停(Stop-The-World,STW)的完整原因分类及对应排查方案,结合JVM运行机制和常见故障场景整理而成: 一、GC相关暂停 1. 安全点(Safepoint)阻塞 现象:JVM暂停但无GC日志,日志显示No GCs detected。原因:JVM等待所有线程进入安全点(如…...
RSS 2025|从说明书学习复杂机器人操作任务:NUS邵林团队提出全新机器人装配技能学习框架Manual2Skill
视觉语言模型(Vision-Language Models, VLMs),为真实环境中的机器人操作任务提供了极具潜力的解决方案。 尽管 VLMs 取得了显著进展,机器人仍难以胜任复杂的长时程任务(如家具装配),主要受限于人…...
Elastic 获得 AWS 教育 ISV 合作伙伴资质,进一步增强教育解决方案产品组合
作者:来自 Elastic Udayasimha Theepireddy (Uday), Brian Bergholm, Marianna Jonsdottir 通过搜索 AI 和云创新推动教育领域的数字化转型。 我们非常高兴地宣布,Elastic 已获得 AWS 教育 ISV 合作伙伴资质。这一重要认证表明,Elastic 作为 …...
华为OD最新机试真题-数组组成的最小数字-OD统一考试(B卷)
题目描述 给定一个整型数组,请从该数组中选择3个元素 组成最小数字并输出 (如果数组长度小于3,则选择数组中所有元素来组成最小数字)。 输入描述 行用半角逗号分割的字符串记录的整型数组,0<数组长度<= 100,0<整数的取值范围<= 10000。 输出描述 由3个元素组成…...
篇章一 论坛系统——前置知识
目录 1.软件开发 1.1 软件的生命周期 1.2 面向对象 1.3 CS、BS架构 1.CS架构编辑 2.BS架构 1.4 软件需求 1.需求分类 2.需求获取 1.5 需求分析 1. 工作内容 1.6 面向对象分析 1.OOA的任务 2.统一建模语言UML 3. 用例模型 3.1 用例图的元素 3.2 建立用例模型 …...
关于疲劳分析的各种方法
疲劳寿命预测方法很多。按疲劳裂纹形成寿命预测的基本假定和控制参数,可分为名义应力法、局部应力一应变法、能量法、场强法等。 1名义应力法 名义应力法是以结构的名义应力为试验和寿命估算的基础,采用雨流法取出一个个相互独立、互不相关的应力循环&…...
SpringCloud——Nacos
1、核心功能: 服务注册与发现: 服务实例可动态注入到Nacos中,消费者通过服务名发现可用实例。 // 启用EnableDiscoveryClient注解启用Nacos SpringBootApplication EnableDiscoveryClient public class UserServiceApplication {public st…...
