详解VHDL如何编写Testbench

1.概述

仿真测试平台文件(Testbench)是可以用来验证所设计的硬件模型正确性的 VHDL模型,它为所测试的元件提供了激励信号,可以以波形的方式显示仿真结果或把测试结果存储到文件中。这里所说的激励信号可以直接集成在测试平台文件中,也可以从外部文件中加载。

一般而言,编写 Testbench 进行测试主要有下面四个步骤

  • (1)实例化需要测试的设计(DUT,Design Under Test);
  • (2)产生模拟激励(波形);
  • (3)将产生的激励加入到被测试模块并观察其输出响应;
  • (4)将输出响应与期望进行比较,从而判断设计的正确性。

其中,输出响应可以以波形方式显示或存储测试结果到文件中。

2.Testbench程序基本结构

通常 Testbench 的基本结构包括库的调用、程序包的调用、空实体、结构体描述。在结构体描述中,一般包含有被测试元件的声明、局部信号声明、被测试元件例化、激励信号的产生,如图所示。与一般的 VHDL 程序不同的是,Testbench 里面的实体为空。
在这里插入图片描述

2.1 被测试元件的声明方式

先说一个被测实体vote7,代码如下:

library ieee;
use ieee.std_logic_1164.all;entity vote7 is port(vt      : in  std_logic_vector(6 downto 0);result  : out std_logic);
end entity vote7;architecture rtl of vote7 is
beginprocess(vt)variable sum : integer range 0 to 7;beginsum := 0;for i in 0 to 6 loopif vt(i) = '1' thensum := sum + 1;if sum > 4 thenresult <= '1';elseresult <= '0';end if;end if;end loop;end process;
end architecture;

2.1.1 组件实例化

组件实例化是一种传统且常用的方法,特别适用于较早版本的VHDL(如VHDL-93)。该方法需要在测试平台中先声明一个组件,然后在架构中进行实例化。

步骤

  • 组件声明:在测试平台的架构声明部分(通常在architecture关键词之后)声明DUT的组件。

  • 实例化:在架构的主体部分使用component实例化DUT,并进行端口映射。
    示例代码

假设有一个被测实体vote7,其声明如下:

library ieee;
use ieee.std_logic_1164.all;entity tb_vote7 is
end entity tb_vote7;architecture Behavioral of tb_vote7 is-- 信号声明……-- 组件声明component vote7port(vt      : in  std_logic_vector(6 downto 0);result  : out std_logic);end component;begin-- DUT实例化DUT: vote7port map (vt      => vt,result  => result);-- 激励过程……
end architecture Behavioral;

2.1.2 直接实体实例化

直接实体实例化(也称为架构实例化)是VHDL-2002及更高版本中引入的一种更简洁的实例化方式。它不需要提前声明组件,直接引用实体和架构即可。

优点

  • 简洁:无需组件声明,减少了代码冗余。
  • 灵活:可以直接指定要使用的实体和架构。

使用与前述相同的vote7实体,测试平台采用直接实体实例化的方法如下:

library ieee;
use ieee.std_logic_1164.all;entity tb_vote7 is
end entity tb_vote7;architecture Behavioral of tb_vote7 is-- 信号声明……
begin-- DUT直接实例化DUT: entity work.vote7(rtl)port map (vt      => vt,result  => result);-- 激励过程……
end architecture Behavioral;

代码解析

  • DUT实例化:使用entity work.vote7(rtl)指定实体vote7和其架构rtl,然后进行端口映射。
  • 无需组件声明:省略了组件的预先声明,代码更加简洁。

3.激励信号的产生

激励信号产生的方式一般有两种,一种是以一定的离散时间间隔产生激励信号,另一种是基于实体的状态产生激励信号。需要注意的是,在 Testbench 程序中一定要对所有的激励信号赋初始值。下面通过实例,讲述激励信号的产生方法。

3.1 时钟信号的产生

时钟信号属于周期性出现的信号,是同步设计中最重要的信号之一。如图所示,时钟信号分为两类,即占空比为50%的对称时钟信号与占空比不是 50%的非对称时钟信号。

在这里插入图片描述
Testbench 中产生时钟信号方式有两种,

  • 一种是使用并行的信号赋值语句;
  • 一种是使用process进程。

下面分别通过两个例子来说明如何用这两种方法来产生所需的时钟信号。

【例】用并行信号赋值语句产生如图所示的 clk1clk2clk3 信号。
在这里插入图片描述
观察上图,我们发现 clk1 为对称时钟信号,其初始值可以在信号定义时赋值;clk2clk3为非对称时钟信号,其起始值可以在语句中赋值。这两种信号的产生方式有所不同,相对而言对称时钟信号的产生相对简单一些。

并行信号赋值语句的实现如下:

signal clk1:std_logic := '0';
signal clk2:std_logic;
signal clk3:std_logic;
……
clk1 <= not clk1 after clk_period/2;
clk2 <= '0' after clk_period/4 when clk2 = '1' else'1' after 3*clk_period/4 when clk2 = '0' else'1';
clk3 <= '0' after clk_period/4 when clk3 = '1' else'1' after 3*clk_period/4 when clk3 = '0' else'0';
……

【例】使用 process 进程产生如图所示的clk1clk2 信号。
在这里插入图片描述
观察上图,可以发现 clk1 为对称时钟信号,clk2 为非对称时钟信号,但这两种信号用 process 进程实现的方法基本一致。

process 进程实现如下:

signal clk1:std_logic;
signal clk2:std_logic;
……
clk1_gen:processconstant clk_period	:time	:= 40ns;--常量只在该进程中起作用beginclk1 <= '1';wait for clk_period/2;clk1 <= '0';wait for clk_period/2;end process;
clk2_gen:processconstant clk_period	:time	:= 20ns; --常量只在该进程中起作用beginclk2 <= '0';wait for clk_period/4;clk2 <= '1';wait for 3*clk_period/4;end process;
……	

3.2 复位信号的产生

Testbench中产生复位信号方式也是两种,一种是并行赋值语句实现,另一种是在进程中设定。下面用例加以说明。

【例 7-5】如图所示,请用并行信号赋值语句产生的reset1信号,用 process 进程产生reset2信号。
在这里插入图片描述
程序如下:

……
signal reset1:std_logic;
signal reset2:std_logic;
……
-- 并行信号赋值语句产生的reset1信号
reset1 <= '0','1' after 20 ns,'0' after 40ns;--用process进程产生reset2信号
reset2_gen:processbeginreset2  <= '0';wait for 20 ns;reset2 <= '1';wait for 40 ns;reset2 <= '0';wait;
end process;
……

3.3 使用delayed属性产生两相关性信号

delayed是VHDL的预定义属性,使用它可以产生两个相关性的信号。如果已经产生了一个时钟信号,在这个时钟信号的基础上,可以使用delayed来使已经产生的时钟信号延迟一点的时间,从而获得另一个时钟信号。

假设已经使用如下的语句定义了一个时钟信号W_CLK:

W_CLK<= '1' after 30 ns when W_CLK= '0' else'0' after 20 ns;

然后可以使用如下的延迟语句获得一个新的时钟信号DLY_W_CLK,它比W_CLK延迟了10 ns:

DLY_W_CLK <= W_CLK' delayed(10 ns);

以上两个时钟信号波形如图所示:

在这里插入图片描述
【例 】 如图所示,请编程实现信号 periodl,period2,要求用到 DELAYED 属性。

在这里插入图片描述
程序如下:

signal period1,period2:std_logic;
……
period1 <= '1' after 30 ns when period1 = '0' else'0' after 20 ns when period1 = '1' else'0';--利用delayed属性,由period1产生period2
period2 <= period1' delayed(10 ns);

3.4 一般激励信号

一般的激励信号通常在 process 进程中定义,而在 process 进程中一般需要使用 wait 语句。所定义的普通的激励信号常用来作模型的输入信号。

【例】 如图 7-18 所示,请编程产生信号 test vectorl 和 test vector2。
在这里插入图片描述
程序如下:

signal test_vector1:std_vector_logic(1 downto 0);
signal test_vector2:std_vector_logic(1 downto 0);
……
TB1:process
begintest_vector1 <= "01";wait for 10 ns;test_vector2 <= "10";wait for 20 ns;
end process;TB2:process
begintest_vector2 <= "01";wait for 10 ns;test_vector2 <= "10";wait;
end process;

【例 】 输入信号 test_abtest_sel 均为 2bit,试用 VHDL 产生这两个输入信号以覆盖所有的输入情况。输入信号向量 test_abtest_sel 均为 2bit,产生的输入情况共有(2x2)x(2x2)=16 种可能。

实现的程序如下

signal test_ab : std_logic_vector(1 downto 0);
signal test_sel:std_logic_vector(1 downto 0);double_loop:process
begintest_ab <= "00";test_sel <= "00";for i in 0 to 3 loopfor j in 0 to 3 loopwait for 10 ns;test_ab <= test_ab + 1;end loop;test_sel <= test_sel + 1;end loop;
end process;

程序对应的波形如图所示:
在这里插入图片描述

特别注意:如果同一个信号在两个进程中进行赋值,若在某些时间段内发生了冲突,就会出现不定状态,如下例所示。因此同一信号不允许在不同进程中赋值。

【例】同一个信号在两个进程中进行赋值,在某些时问段内发生了冲突,出现不定状态的情况。

程序如下:

……
signal test_vector:std_logic_vector(2 downto 0);
signal reset:std_logic;
……
gen_1:process
beginreset <= '1';wait for 100 ns;reset <= '0';test_vector <= "000";wait;
end process;gen_2:process
beginwait for 200 ns;test_vector <= "001";wait for 200 ns;test_vector <= "011";
end process;
……

对应的波形如图所示:

在这里插入图片描述

3.5 动态激励信号

动态激励信号,就是输入激励信号与被仿真的实体(DUT)的行为模型相关,即 DUT 的输入激励信号受模型的行为所影响。

如下信号的定义,模型的输入信号 sig_A 就和模型输出信号 count 相关。

process(count)
begincase count iswhen 2 =>sig_A <= '1' after 10 ns;when others =>sig_A <= '0' after 10 ns;end case;
end process;

3.6 测试矢量

在实际应用中,常常将一组固定的输入输出矢量值存储在一个常量表或一个 ASCI 文件中,然后将这些值应用到输入信号从而产生激励信号。这里所说的固定输入输出矢量值就称为测试矢量。矢量的值序列可以使用多维数组或使用多列记录来描述。

如下面的数据表存储了输入矢量:

constant no_of_bits:integer := 4;
constant no_of_vectors:integer := 5;
type table_type is array (1 to no_of_bits) of std_logic_vector(1 to no_of_vectors);
constant input_vectors:table_type := ("1001","1000","0010","0000","0110");signal inputs:std_logic_vector(1 to no_of_vectors);
signal A,B,C:std_logic;
signal D:std_logic_vector(0 to 1);

假设所测试的实体(DUT)具有4个输入:A、B、C和D信号,如果以一般的时间间隔应用测试矢量,则可以使用一个generate语句,例如

G1:for j in 1 to no_of_vectors generateinputs <= input_vectors(j) after (vector_period*j);
end generate;A <= inputs(1);B <= inputs(4);C <= inputs(1);D <= inputs(2 to 3);

如果将信号应用于任意时间间隔,则需要使用并行的信号赋值语句产生多个信号的波形,使用这种方法可以将一个矢量赋值给多个信号,如下面的代码:

inputs <= input_vector(1) after 10 ns;input_vector(2) after 25 ns;input_vector(3) after 30 ns;input_vector(4) after 32 ns;input_vector(5) after 40 ns;

4.高级Testbench编写

高级Testbench 是在简单 Testbench 基础上改进的,能够自动读入测试矢量文件、完成输出值和期望值的比较等功能,如图所示。相比简单Testbench,高级 Testbench 更显得智能化,也减少了人工分析的烦琐工作。

在这里插入图片描述

4.1 文件I/O的读写

仿真时,VHDL 允许设计人员从文件加载数据或将数据存储到文件中。比如用户定义的测试矢量可以保存在文件中,然后在仿真时从文件中读取这些测试矢量。另外,仿真的结果也可以保存在文件中。

VHDL 标准中的文件 I/O 主要是由 TEXTIO 程序包提供的,用于仿真且综合工具不能综合标准库 STD 中的 TEXTIO 定义的程序包只能使用 BIT 和 BIT_VECTOR 数据类型,其引用的格式为:

library std;
use std.textio.all;

如果要使用std_logicstd_logic_vector,则需要调用std_logic_textio,格式为:

library ieee;
use ieee.std_logic_textio.all;

4.1.1 TEXTIO介绍

TEXTIO 是 VHDL 标准库 STD 中的一个程序包(package)。在该包中定义了三个基本类型:LINE 类型、TEXT 类型以及 SIDE 类型。另外,还有一个子类型(subtype)WIDTH。此外,在该程序包中还定义了一些访问文件所必须的过程(procedure),如图所示。

在这里插入图片描述
其中,TEXT为ASCII文件类型。定义成TEXT类型的文件是长度可变的ASCII文件,需要注意的是VHDL’87 和 VHDL’93 在使用文件方面由较大的差异,在编译时注意选择对应的标准。

side只能有两种状态,即rightleft,分别表示将数据从左边还是从右边写入行变量。该类型主要是在TEXTIO程序包包含的过程中使用。

WIDTH为自然数的子类型。所谓子类型表示其取值范围是父类型范围的子集。

TEXTIO 也提供了基本的用于访问文本文件的过程。类似于 C++,VHDL 提供了重载功能,即完成相近功能的不同过程可以有相同的过程名,但其参数列表不同,或参数类型不同或参数个数不同。

TEXTIO 提供的基本过程有:

1.procedure READLINE(文件变量;行变量);

用于从指定文件读取一行数据到行变量中。

2.procedure WRITELINE(文件变量:行变量):

用于向指定文件写入行变量所包含的数据。

3.procedure READ(…);

可重载,用于从行变量中读取相应数据类型的数据。

4.procedure WRITE(…);

可重载,用于将数据写入行变量

4.1.2 文件基本操作

1.定义文件

TEXTIO 程序包中可操作的文件主要包含两大类:integertext

integer 文件中的数据是以二进制存取的,不能被人识别,只有 integer 型的数据能够存入这类文件。

text 文件是可以读取的 ASCI 码,可以被人识别。integer 、bit vector(x downto x)、string(x downto 1)、std logic_vector(x downto 0)及 bit 等类型都可以被存入此类文件。

对文件进行操作之前,需要对将要进行操作的文件进行定义,在 93 版的 VHDL 中,文件定义的方式如下:

FIE file handle: text open read mode is"目录十文件.后缀"---(输入文件的说明)
FIE file handle: text open write mode is"目录十文件.后缀"---(输出文件的说明)

在 87 版的 VHDL 中,文件定义的方式:

FIEL file handle: text is in"目录十文件.后缀"---(输入文件的说明)
FIEL file handle: text is out"目录十文件.后缀"---(输出文件的说明)

如果在支持 93 版的 VHDL 语言中使用了 87 版的格式,仿真时会提示:

warning: FIE declaration was written using 1076-1987 syntax.

2.打开文件

定义文件句柄后就可以在程序中打开指定文件,同时指定打开模式。93 版的 VHDL 可以使用 file open()进行文件打开操作,其中文件打开操作的函数使用方法如下:

file_open(fstatus,file_handle,filename)

其中,fstatus指示当前文件状态,但是在使用前首先得定义:

variable fatatus:file_open_status;

状态一般有四种,即open_ok,status_error,name_error,mode_error

file handle 即是上一步定义的文件句柄file handle

filename 是以双引号括起的文件名,如"datain.txt",也可以加上文件路径。openmode 是指打开该文件的模式,文件打开有read_mode,write mode,append_mode 三种。

3.读写文件

打开文件后就可以对文件进行读写操作,其语句格式如下:

--将文件中的一行数据读至行变量中。
realine(文件变量,行变量);--行变量中保存的数据取n位放至数据变量v中,n为数据变量v的数据位数。在此之前,需要定义好行变量和数据变量。
read(行变量,数据变量);--将一个数据写到某一行中。
write(行变量,数据变量);--起始位置为left 或 righ,字符数则表示数据变量写入到行变量后占的位宽。
write(行变量,数据变量,起始位置,字符数);--将行变量包含的数据写入到指定文件;
wwriteline(文件变量,行变量);

4.关闭文件

在文件读写完毕后,需使用 file)close(file handle)关闭文件。

如果想判断在文件操作中是否读取到文件的末尾,可以使用函数endfile(file_handle)进行判断,如果到达文件末尾将返回“真(true)”,否则返回“假(false)”。

下面举一个例子,使用了上面介绍的各种语法。

【例】文件I/O读写例程

library ieee;
library std;use std.textio.all;
use ieee.std_logic_textio.all;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;entity testin is
end entity testin;architecture rtl of testin is
beginprocess-- 定义text类型得文件句柄file file_out1,file_in:text; -- 定义文件状态指示变量variable fstatus1,fstatus2:file_open_status;variable count:integer := 5;variable stringdata:string(5 downto 1) := "SCUTE"; --string型variable vectordata:bit_vector(5 downto 0) := "001000";variable value:std_logic_vector(3 downto 0) := "1111";variable buf,buf1:line;begin--创建并打开文件file_open(fstatus1,file_out1,"DATAIN.TXT",write_mode);write(file_out1,string'("THE FIRST PAPAMETER IS ="));readline(input,buf);write(buf,count);writeline(file_out1,buf);wait for 20 ns;write(buf,string'(THE SECOND PAPAMETER IS = "));write(buf,value);writeline(file_out1,buf);wait for 20 ns;write(buf,string'("THE THIRD PAPAMETER IS = "));write(buf,vectordata);writeline(file_out1,buf);wait for 20 ns;write(buf,string'("THE FORTH PAPAMETER IS = "));write(buf,stringdata);writeline(file_out1,buf);write(file_out1,string'("END OF FILE"));file_close(file_out1);wait for 100 ns;file_open(fstatus1,file_out1,"DATAIN.TXT",read_mode);readline(file_out1,buf);writeline(output,buf);file_close(file_out1);wait for 100 ns;file_open(fstatus1,file_in,"STD_INPUT",read_mode);file_open(fstatus2,file_out1,"STD_OUTPUT",write_mode);readline(file_in,buf);writeline(file_out1,buf);wait;end process;
end rtl;

在modelsim中运行,控制台将做如下操作:

在这里插入图片描述
等待数秒后,在modelsim工程目录下将会新建一个“DATAIN.TXT”文本文档,打开文档其内容如图所示:

在这里插入图片描述

4.2 断言语句

断言语句(Assert)语句可以在仿真的过程中,检查一个条件并报告信息,一般用于程序调试与时序仿真时的人机对话,也是不可综合的语句。

断言语句的书写格式为:

assert<条件表达式>report<出错信息>severity<错误级别>;

其中,ASSERT 后的条件表达式为布尔表达式,用于模拟执行时的真假判断。若其值为“真”则跳过下面两个子句,继续执行后面的语句;若其值为“假”,则表示出错,于是执行 REPORT报告出错信息,同时由 SEVERITY 子句给出错误等级。

ASSERT 后的条件表达式由设计人员自行拟定,没有默认格式。断言语句里面的出错信息与错误等级也都由设计者自行设计,VHDL不自动生成这些信息。而且,REPORT 后的出错信息必须是字符串,需要用双括号括起来,若缺省出错信息,则系统默认输出错误信息报告为"Assertion Violation"。SEVERITY 后的错误级别要求是预定义的四种错误之一, 预定义的四种错误类型分别是:Note(通报)、Warning(警告)、Error(错误)、Failure(失败)。若缺省,则默认为 Error。

4.2.1 断言语句的使用方法

断言语句可以在实体、结构体以及进程中使用。下面通过一个例子初步介绍断言语句在仿真时的应用。

【例】用断言语句判断仿真的时间,如果当前时间为1000ns,则仿真完成,使用 ERROR严重级别终止仿真过程。

程序如下:

process
begin
assert(now <= 1000 ns)report "simulation completed successfully"severity error;
end process;

断言语句判断条件的判断结果为 FALSE,则执行后面的报告及严重级语句,否则跳过这些错误报告语句并继续执行。

放在进程内的断言语句叫顺序断言语句,它在进程内按照顺序执行。放在进程外部的断言语句叫并行断言语句。并行断言语句本质上等同于一个进程,该进程只对条件表达式给出的所有信号敏感。

如果把断言语句单独放在一个进程里面,则该进程称为断言进程。断言进程只能放在结构体里面,且不对任何信号进行赋值操作。下例就是一个断言进程语句。

【例】 使用 ASSERT 语句设定一个判断条件,以便对仿真的某个结果或值做出响应

……
process(q)
begin
assert(q /= "1001")report "the shifter gets the result!"severity error;
end process;

在上面的程序中,如果信号q等于“1001”,则终止仿真,并输出 The shifter gets the result!。

4.2.2 断言语句的应用实例

下面以一个简单的实例来讲述使用断言语句来响应一个仿真的过程。

【例】 4位加减计数器的仿真。所述4位加减计数器的位数为4位,且带有 CLR 清零端。当 DIR 信号为高电平时,计数器为加1计数器;当 DIR 信号为低电平时,为减1计数器。

4 位加减计数器的设计程序如下:

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;entity counter is port(clk,clr,dir:in	std_logic;result	   :out	std_logic_vector(3 downto 0));
end entity counter;architecture rtl of counter is
signal tmp:std_logic_vector(3 downto 0);
begin
process(clk,clr)
beginif(clr = '1') thentmp <= "0000";elsif(clk' event and clk = '1') thenif(dir = '1') thentmp <= tmp + 1;elsetmp <= tmp - 1;end if;end if;
end process;result <= tmp;end rtl;

4位加减计数器的仿真程序如下:

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned;entity tb_counter is
end entity tb_counter;atchitecture rtl of tb_counter issignal clk      :std_logic := '0';
signal clr		:std_logic := '0';
signal dir		:std_logic := '0';
signa result 	:std_logic_vector(3 downto 0);
constant clk_period:time := 40 ns;beginuut:entity work.counter(rtl)port map(clk => clk,clr => clr,dir => dir,result => result);clk_gen:process
beginclk <= '0';wait for clk_period/2;clk <= '1';wait for clk_period/2;
end process;TB:process
beginclr <= '1';dir <= '1';wait for 20 ns;clr <= '0';wait for 280 ns;dir <= '0';wait for 320 ns;wait;
end process;process(result)
beginassert(result /= "1001")report "THe counter gets to nine!"severity error;
end process;
end rtl;

仿真波形如下图所示:
在这里插入图片描述

当计数到“1001”时,在信息栏输出

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/65348.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

深度学习:从原理到搭建基础模型

引言: 深度学习为什么火? 深度学习在处理复杂的感知和模式识别任务方面展现出了前所未有的能力。以图像识别为例,深度学习模型(如卷积神经网络 CNN)能够识别图像中的各种物体、场景和特征,准确率远超传统的计算机视觉方法。 当然这之中也还因为 大数据时代的推动(随着…

c语言中void关键字的含义和用法

在 C 语言中&#xff0c;void 是一个特殊的关键字&#xff0c;主要有以下几个用途&#xff1a; 1. 表示函数没有返回值 当一个函数不需要返回任何值时&#xff0c;可以将其返回类型声明为 void。 #include <stdio.h>void printMessage() {printf("Hello, World!\…

RNA-Seq 数据集、比对和标准化

RNA-Seq 数据集、比对和标准化|玉米中的元基因调控网络突出了功能上相关的调控相互作用。 RNA-Seq 表达分析代码和数据 该仓库是一个公开可用 RNA-Seq 数据集的集合&#xff08;主要是玉米数据&#xff09;&#xff0c;提供了系统分析这些数据的代码/流程&#xff0c;以及质量…

学技术学英文:Spring AOP和 AspectJ 的关系

AspectJ是AOP领域的江湖一哥&#xff0c; Spring AOP 只是一个小弟 Spring AOP is implemented in pure Java. There is no need for a special compilation process. Spring AOP does not need to control the class loader hierarchy and is thus suitable for use in a ser…

JVM学习-内存结构(二)

一、堆 1.定义 2.堆内存溢出问题 1.演示 -Xmx设置堆大小 3.堆内存的诊断 3.1介绍 1&#xff0c;2都是命令行工具&#xff08;可直接在ideal运行时&#xff0c;在底下打开终端&#xff0c;输入命令&#xff09; 1可以拿到Java进程的进程ID&#xff0c;2 jmap只能查询某一个时…

Browser Use:AI智能体自动化操作浏览器的开源工具

Browser Use:AI智能体自动化操作浏览器的开源工具 Browser Use 简介1. 安装所需依赖2. 生成openai密钥3. 编写代码4. 运行代码5. 部署与优化5.1 部署AI代理5.2 优化与扩展总结Browser Use 简介 browser-use是一个Python库,它能够帮助我们将AI代理与浏览器自动化操作结合起来;…

Spring Cloud——注册中心

介绍 什么是注册中心&#xff1f; 主要负责服务的注册与发现&#xff0c;确保服务之间的通信顺畅&#xff0c;具体来说&#xff0c;注册中心有以下主要功能&#xff1a;‌服务注册、服务发现、服务健康检查。 服务注册&#xff1a; 服务提供者在启动时会向注册中心注册自身服务…

CSS基础入门【2】

目录 一、知识复习 二、权重问题深入 2.1 同一个标签&#xff0c;携带了多个类名&#xff0c;有冲突&#xff1a; 2.2 !important标记 2.3 权重计算的总结 三、盒模型 3.1 盒子中的区域 3.2 认识width、height 3.3 认识padding 3.4 border 作业&#xff1a; 一、知识…

MATLAB语言的计算机基础

标题&#xff1a;MATLAB语言的计算机基础&#xff1a;探索科学计算的无限可能 一、引言 在当今这个数据爆炸的时代&#xff0c;科学计算和数据分析的重要性不言而喻。MATLAB作为一种高级的、交互式的编程环境&#xff0c;以其强大的数值计算能力、直观的图形展示以及丰富的工…

软路由系统 iStoreOS 中部署 Minecraft 服务器

商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处。协议(License): 知识共享署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)作者(Author): lhDream链接(URL): https://blog.luhua.site/archives/1734968846131 软路由系统 iStoreOS 中部署 Minecraft…

.net core 的函数实现

Python基础 Python是一种广泛使用的高级编程语言&#xff0c;以其简洁易读的语法和强大的功能而闻名。它被广泛应用于数据分析、人工智能、网站开发、自动化脚本及其他众多领域。本文将详细介绍Python的基础知识&#xff0c;包括其安装及环境配置、基本语法、数据类型、控制结…

捋一捋相关性运算,以及DTD和NLP中的应用

捋一捋相关性运算&#xff0c;以及DTD和NLP中的应用 相关性和相干性,有木有傻傻分不清相关性数字信号的相关运算同维度信号的相关理解 相关--互相关--相干 回声消除过程如何套用这些知识相关性/相干性检测在DT中的应用时域的标量与向量结合的互相关方法适合block处理的频域相干…

Elasticsearch:normalizer

一、概述 ‌Elastic normalizer‌是Elasticsearch中用于处理keyword类型字段的一种工具&#xff0c;主要用于对字段进行规范化处理&#xff0c;确保在索引和查询时保持一致性。 Normalizer与analyzer类似&#xff0c;都是对字段进行处理&#xff0c;但normalizer不会对字段进…

go语言的成神之路-筑基篇-对文件的操作

目录 一、对文件的读写 Reader?接口 ?Writer接口 copy接口 bufio的使用 ioutil库? 二、cat命令 三、包 1. 包的声明 2. 导入包 3. 包的可见性 4. 包的初始化 5. 标准库包 6. 第三方包 ?7. 包的组织 8. 包的别名 9. 包的路径 10. 包的版本管理 四、go mo…

SQL Server中FIRST_VALUE和 LAST_VALUE窗口函数允许在一个指定的窗口内返回第一个或最后一个值

在 SQL Server 中&#xff0c;FIRST_VALUE 和 LAST_VALUE 是用于窗口函数&#xff08;Window Functions&#xff09;的两个非常有用的函数。它们允许你在一个指定的窗口内返回第一个或最后一个值。这两个函数通常与 OVER 子句一起使用&#xff0c;以定义窗口的范围和排序规则。…

【入门】拐角III

描述 输入整数N&#xff0c;输出相应方阵。 输入描述 一个整数N。&#xff08; 0 < n < 10 ) 输出描述 一个方阵&#xff0c;每个数字的场宽为3。 用例输入 1 5 用例输出 1 5 5 5 5 55 4 4 4 45 4 3 3 35 4 3 2 25 4 3 2 1 来源 二维数组…

攻防世界 ics-06

开启场景 可以交互的按钮不是很多&#xff0c;没有什么有用信息&#xff0c;查看页面源代码找到了index.php &#xff0c;后面跟着“报表中心” 传参访问 /index.php 看到了参数 id1&#xff0c;用 burp 抓包爆破&#xff08;这里应该不是 sql 注入&#xff09; 2333 的长度与众…

VMware虚拟机安装银河麒麟操作系统KylinOS教程(超详细)

目录 引言1. 下载2. 安装 VMware2. 安装银河麒麟操作系统2.1 新建虚拟机2.2 安装操作系统2.3 网络配置 3. 安装VMTools 创作不易&#xff0c;禁止转载抄袭&#xff01;&#xff01;&#xff01;违者必究&#xff01;&#xff01;&#xff01; 创作不易&#xff0c;禁止转载抄袭…

ByConity BSP 解锁数据仓库新未来

文章目录 前言BSP 模式简介基于 TPC-DS 的 ELT 活动测试环境登录 ECS数据查询配置 执行 02.sqlsql解释&#xff1a;1. 第一步&#xff1a;创建 wscs 临时表2. 第二步&#xff1a;创建 wswscs 临时表3. 第三步&#xff1a;对比 2001 年和 2002 年的数据子查询 1&#xff1a;提取…

Sql Sqserver 相关知识总结

Sql Sqserver 相关知识总结 文章目录 Sql Sqserver 相关知识总结前言优化语句查询&#xff08;select&#xff09;条件过滤&#xff08;Where&#xff09;分组处理&#xff08;GROUP BY&#xff09;模糊查询&#xff08;like&#xff09;包含&#xff08;in&#xff09;合集&am…