Riscv 架构的合规测试

为啥直接关注riscv-arch-test,是因为RISCOF 测试框架使用的是riscv-arch-test
在这里插入图片描述

1. The architectural test

架构测试是一个单一的测试,代表了可编译和运行的最小测试代码。它是用汇编代码编写的,其产品是test signature。一个架构测试可能由多个测试用例组成。

2. The RISC-V architectural test pool

RISC-V 架构测试池由所有经批准的架构测试组成,这些测试可由测试框架编译,形成架构测试套件。RISC-V 架构测试库必须与测试目标无关(因此,应能在任何符合要求的目标上正确运行)。请注意,这种非功能测试不能替代验证或器件测试。

2.1 Test pool structure

architectural-tests-suite (root)
|-- <architecture>_<mode>/<feature(s)>, where
<architecture> is [ RV32I | RV64I | RV32E ]
<mode> is [ M | MU | MS | MSU ], whereM   Machine      mode tests - tests execute in M-mode onlyMU  Machine/User mode tests - tests execute in both M- & U-modes (S-mode may exist)MS  Machine/Supv mode tests - tests execute in both M- & S-modes (not U-mode)MSU All          mode tests - tests execute in all of M-, S-, & U-Modes
<feature(s)> are the lettered extension [A | B | C | M ...] or subextension [Zifencei | Zam | ...] when the tests involve extensions, or more general names when tests cut across extension definitionss (e.g. Priv, Interrupt, Vm). The feature string consists of an initial capital letter, followed by any further letters in lower case.

机器模式处理器指令集特性寄存器(MISA)
misa = 0x800000000094112f
二进制表示:1000000000000000000000000000000000000000100101000001000100101111
在这里插入图片描述

riscv-arch-test/riscv-test-suite$ ls
env/ Makefile.include README.md rv32e_m/ rv32i_m/ rv64i_m/
riscv-arch-test/riscv-test-suite/rv64i_m$ ls
A/ B/ C/ CMO/ D/ F/ I/ K/ M/ privilege/ P_unratified/ Zfh/ Zfinx/ Zicond/ Zifencei/

3. The RISC-V architectural test suite

RISC-V 架构测试套件是从架构测试池中选出的一组测试,用于测试特定 RISC-V 配置的一致性。测试结果以 test suite signature的形式获得。测试的选择基于目标的断言配置、规范、执行环境或平台要求。合规的处理器或处理器模型应显示与所测试的特定配置的黄金参考测试套件签名相同。

4. The test case

测试用例是架构测试的一部分,只测试规范的一个功能。
注意:一个测试可以包含多个测试用例,每个测试用例都有自己的测试包含条件(由 RVTEST_CASE 宏的 cond_str 参数定义)。

4.1 Test命名

<test objective>-<test number>.S

riscv-arch-test/riscv-test-suite/rv64i_m/I/src$ ls
add-01.S and-01.S bge-01.S bne-01.S lb-align-01.S lhu-align-01.S misalign1-jalr-01.S sd-align-01.S slliw-01.S sltiu-01.S sraiw-01.S srliw-01.S sw-align-01.S
addi-01.S andi-01.S bgeu-01.S fence-01.S lbu-align-01.S lui-01.S or-01.S sh-align-01.S sllw-01.S sltu-01.S sraw-01.S srlw-01.S xor-01.S
addiw-01.S auipc-01.S blt-01.S jal-01.S ld-align-01.S lw-align-01.S ori-01.S sll-01.S slt-01.S sra-01.S srl-01.S sub-01.S xori-01.S
addw-01.S beq-01.S bltu-01.S jalr-01.S lh-align-01.S lwu-align-01.S sb-align-01.S slli-01.S slti-01.S srai-01.S srli-01.S subw-01.S

5. Assembly Test Infrastructure (以./rv32i_m/I/src/add-01.S为例)

//
// This assembly file tests the add instruction of the RISC-V I extension for the add covergroup.
// 
#include "model_test.h"
#include "arch_test.h"
RVTEST_ISA("RV32I").section .text.init
.globl rvtest_entry_point
rvtest_entry_point:
RVMODEL_BOOT
RVTEST_CODE_BEGIN#ifdef TEST_CASE_1RVTEST_CASE(0,"//check ISA:=regex(.*32.*);check ISA:=regex(.*I.*);def TEST_CASE_1=True;",add)RVTEST_SIGBASE( x3,signature_x3_1)inst_0:
// rs2 == rd != rs1, rs1==x4, rs2==x24, rd==x24, rs1_val > 0 and rs2_val > 0, rs2_val == 1, rs1_val == (2**(xlen-1)-1), rs1_val != rs2_val, rs1_val == 2147483647
// opcode: add ; op1:x4; op2:x24; dest:x24; op1val:0x7fffffff;  op2val:0x1
TEST_RR_OP(add, x24, x4, x24, 0x80000000, 0x7fffffff, 0x1, x3, 0, x18)inst_1:
// rs1 == rs2 != rd, rs1==x10, rs2==x10, rd==x28, rs1_val > 0 and rs2_val < 0, rs2_val == -257, rs1_val == 131072
// opcode: add ; op1:x10; op2:x10; dest:x28; op1val:0x20000;  op2val:0x20000
TEST_RR_OP(add, x28, x10, x10, 0x40000, 0x20000, 0x20000, x3, 4, x18)inst_2:
// rs1 == rs2 == rd, rs1==x21, rs2==x21, rd==x21, rs1_val < 0 and rs2_val < 0, rs1_val == -16777217
// opcode: add ; op1:x21; op2:x21; dest:x21; op1val:-0x1000001;  op2val:-0x1000001
TEST_RR_OP(add, x21, x21, x21, 0xfdfffffe, -0x1000001, -0x1000001, x3, 8, x18)
......
......
......
RVTEST_CODE_END
RVMODEL_HALTRVTEST_DATA_BEGIN
.align 4rvtest_data:
.word 0xbabecafe
.word 0xbabecafe
.word 0xbabecafe
.word 0xbabecafe
RVTEST_DATA_ENDRVMODEL_DATA_BEGIN
rvtest_sig_begin:
sig_begin_canary:
CANARY;signature_x3_0:.fill 0*(XLEN/32),4,0xdeadbeefsignature_x3_1:.fill 17*(XLEN/32),4,0xdeadbeefsignature_x8_0:.fill 16*(XLEN/32),4,0xdeadbeefsignature_x1_0:.fill 512*(XLEN/32),4,0xdeadbeefsignature_x1_1:.fill 43*(XLEN/32),4,0xdeadbeef#ifdef rvtest_mtrap_routinetsig_begin_canary:
CANARY;
mtrap_sigptr:.fill 64*(XLEN/32),4,0xdeadbeef
tsig_end_canary:
CANARY;#endif#ifdef rvtest_gpr_savegpr_save:.fill 32*(XLEN/32),4,0xdeadbeef#endifsig_end_canary:
CANARY;
rvtest_sig_end:
RVMODEL_DATA_END

简单对上面的汇编代码解释如下:

  1. Header to inlcude comments

#This assembly file tests the add instruction of the RISC-V I extension for the add covergroup.

  1. Includes header files

#include “model_test.h”
#include “arch_test.h”

每个测试应只包括以下头文件:
model_test.h - 定义特定于目标的宏,包括必填的宏和可选的宏:(如 RVMODEL_xxx)
arch_test.h - 定义预定义的测试宏,包括必填的宏和可选的宏:(如 RVTEST_xxx)

  1. Set the TVM of the test

RVTEST_ISA(“RV32I”)

  1. Test target specific boot-code

RVMODEL_BOOT

  1. Start of GPR initialization routine and test code

RVTEST_CODE_BEGIN

  1. Define the RVTEST_CASE string and conditions

#ifdef TEST_CASE_1
// this test is meant for devices implementing rv32I extension and requires enabling the compile
// macro TEST_CASE_1. This test will contribute to the “add” coverage label.
RVTEST_CASE(0,“//check ISA:=regex(.32.);check ISA:=regex(.I.);def TEST_CASE_1=True;”,add)

  1. Initialize pointer to the signature region

RVTEST_SIGBASE( x16,signature_x16_1) // x16 will point to signature_x16_1 label in the signature region

  1. Define the test cases
inst_0:
// rs2 == rd != rs1, rs1==x4, rs2==x24, rd==x24, rs1_val > 0 and rs2_val > 0, rs2_val == 1, rs1_val == (2**(xlen-1)-1), rs1_val != rs2_val, rs1_val == 2147483647
// opcode: add ; op1:x4; op2:x24; dest:x24; op1val:0x7fffffff;  op2val:0x1
TEST_RR_OP(add, x24, x4, x24, 0x80000000, 0x7fffffff, 0x1, x3, 0, x18)inst_1:
// rs1 == rs2 != rd, rs1==x10, rs2==x10, rd==x28, rs1_val > 0 and rs2_val < 0, rs2_val == -257, rs1_val == 131072
// opcode: add ; op1:x10; op2:x10; dest:x28; op1val:0x20000;  op2val:0x20000
TEST_RR_OP(add, x28, x10, x10, 0x40000, 0x20000, 0x20000, x3, 4, x18)
...
...
//Tests for a instructions with register-register operand
#define TEST_RR_OP(inst, destreg, reg1, reg2, correctval, val1, val2, swreg, offset, testreg) \TEST_CASE(testreg, destreg, correctval, swreg, offset, \LI(reg1, MASK_XLEN(val1))                        ;\LI(reg2, MASK_XLEN(val2))                        ;\inst destreg, reg1, reg2                        ;\)
#define TEST_CASE(testreg, destreg, correctval, swreg, offset, code... )        ;\code                                ;\RVTEST_SIGUPD(swreg,destreg,offset)        ;\RVMODEL_IO_ASSERT_GPR_EQ(testreg, destreg, correctval)/* automatically adjust base and offset if offset gets too big, resetting offset                                 *//* RVTEST_SIGUPD(basereg, sigreg)          stores sigreg at offset(basereg) and updates offset by regwidth         *//* RVTEST_SIGUPD(basereg, sigreg,newoff) stores sigreg at newoff(basereg) and updates offset to regwidth+newoff */
#define RVTEST_SIGUPD(_BR,_R,...)                        ;\.if NARG(__VA_ARGS__) == 1                                ;\.set offset,_ARG1(__VA_OPT__(__VA_ARGS__,0))        ;\.endif                                                ;\CHK_OFFSET(_BR, REGWIDTH,0)                                ;\SREG _R,offset(_BR)                                        ;\.set offset,offset+REGWIDTHRVMODEL_IO_ASSERT_GPR_EQ 定义在target的model_test.h中```在咱们得model_test.h中将RVMODEL_IO_ASSERT_GPR_EQ 宏定义如下:比较错误的话,往0xF00000801```c
#define RVMODEL_IO_ASSERT_GPR_EQ(_S, _R, _I)  \li _S, 0xF0000080;         \mv t0, _R;                 \li t3, _I;                 \beq t0, t3, 1f;            \li t2, 1;                  \sw t2, 0(_S);              \j 2f;                      \
1:                             \li t2, 0;                  \sw t2, 0(_S);              \
2:                             \nop;```在tb.v中加入监测对AXI 写地址总线,地址0xF0000080的监测,如果出现fail_cnt >0,可以判断该testcase错误```c
// RVMODEL_IO_ASSERT_GPR_EQ(testreg, destreg, correctval) used to check destreg == correctval
// destreg != correctva write testreg 1, else write testreg 0
always @(posedge `CPU_CLK) beginif ((cpu_awaddr[31:0] == 32'hF000_0080) && cpu_wvalid && `clk_en && (cpu_wstrb[15:0] == 16'hf)) beginif(`SOC_TOP.biu_pad_wdata == 1'b1) beginfail_cnt ++;endend
end
  1. Change signature base register
// this will change the signature base register to x3. x3 will not point to signature_x3_0 in
// the signature region
RVTEST_SIGBASE( x3,signature_x3_0)// continue with new test cases ..
TEST_RR_OP(add, x4, x24, x27, 0x55555955, 0x00000400, 0x55555555, x3, 0, x5)
...
...
  1. End the test and halt the test-target
RVTEST_CODE_END
RVMODEL_HALT
  1. Create test input data section
RVTEST_DATA_BEGIN
rvtest_data:
.word 0xbabecafe
RVTEST_DATA_END
  1. Create pre-loaded signature region
RVMODEL_DATA_BEGIN
rvtest_sig_begin:
sig_begin_canary:
CANARY;signature_x3_0:.fill 0*(XLEN/32),4,0xdeadbeefsignature_x3_1:.fill 17*(XLEN/32),4,0xdeadbeefsignature_x8_0:.fill 16*(XLEN/32),4,0xdeadbeefsignature_x1_0:.fill 512*(XLEN/32),4,0xdeadbeefsignature_x1_1:.fill 43*(XLEN/32),4,0xdeadbeef#ifdef rvtest_mtrap_routinetsig_begin_canary:
CANARY;
mtrap_sigptr:.fill 64*(XLEN/32),4,0xdeadbeef
tsig_end_canary:
CANARY;#endif#ifdef rvtest_gpr_savegpr_save:.fill 32*(XLEN/32),4,0xdeadbeef#endifsig_end_canary:
CANARY;
rvtest_sig_end:
RVMODEL_DATA_END

6. The test case signature

测试用例signature由单个或多个值表示。值将以 RVMODEL_DATA_BEGIN 指定的地址为起点,以 RVMODEL_DATA_END 指定的地址为终点写入内存。使用 RVTEST_SIGUPD 宏很容易生成signature。

7. The test signature

测试 signature 是由architectural test运行生成的特征值。测试 signature可能由多个测试用例 signature 组成,前缀是一个单独的行,其中包含测试的名称和表示其版本的唯一值。测试target负责从内存中提取值并适当地格式化它们,使用由框架提供的元数据,使用 RVMODEL_DATA_BEGIN 和 RVMODEL_DATA_END 宏。测试用例 signature 值按行写入,从最左边的最高有效字节开始,格式为 <hex_value>,其中值的长度将为 32 位(因此为 8 个字符),而实际测试计算的值长度不考虑。文件应从 signature 的最低地址处的值开始存储(即从 RVMODEL_DATA_BEGIN 到 RVMODEL_DATA_END)。此外,signature 应始终从 16 字节(128 位)边界开始,signature的大小应为 4 字节的倍数(即也应以 4 字节边界结束)。

8. The test suite signature

测试套件 signature 被定义为一组对于给定的架构测试套件有效的测试 signature。它代表了选择的特定 RISC-V 配置的架构测试套件的测试 signature。

9. RISCOF 测试框架

RISCOF - RISC-V 兼容性框架是一个基于 Python 的框架,它使得可以使用一套 RISC-V 架构测试集来测试 RISC-V 目标(硬件或软件实现)与标准的 RISC-V 黄金参考模型的兼容性。
在这里插入图片描述
RISC-V Configuration Validator : RISCV-Config
RISC-V Compliance Test Generator : RISC-V CTG
RISC-V ISA Coverage : RISC-V ISAC
为了RISCOF能正常运行测试,需要提供以下内容:

  • config.ini:这个文件是一个基本的配置文件,遵循 ini 语法。这个文件将捕获信息,比如:DUT/reference 插件的名称,插件的路径,基于 riscv-config 的 YAML 文件的路径等。
  • dut-plugin 目录:RISCOF 要求测试的 DUT 模型以 Python 插件的形式提供。Python 插件实际上就是一个包含某些标准和定义函数的 Python 文件,用于执行测试编译、执行和签名提取的活动。这个 Python 文件的名称需要以 riscof_ 为前缀,并且必须存在于 dut-plugin 目录中。可以参考 Python 插件文件部分,了解如何编写这个 Python 文件。
    该目录还需要包含基于 riscv-config 的 isa 和 platform YAML 文件,这些文件提供了 DUT 的定义。这些 YAML 文件将用于过滤需要在 DUT 上运行的测试。
    最后,在 dut-plugin 目录中还需要存在一个 env 目录,其中包含环境文件,如 model_test.h,这是编译和运行测试所需的文件。请参考 TestFormat 规范,了解可以在 model_test.h 文件中使用的宏的定义。env 目录还可能包含其他文件,如链接脚本、用户可能需要的后处理脚本。
  • reference-plugin 目录:与 DUT 插件类似,RISCOF 也需要一个参考模型插件。目录和文件的结构与 DUT 的相同。但是,不需要 isa 和 platform YAML 文件,因为 RISCOF 将始终从 DUT 插件中选择所有目的的 YAML 文件。
    为了简化操作,RISCOF 通过设置命令为用户生成标准的 DUT 和参考模型预置模板,如下图所示:

$ riscof setup --dutname=spike

上述命令将在当前目录下生成以下文件和目录:

├──config.ini # configuration file for riscof
├──spike/ # DUT plugin templates
├── env
│ ├── link.ld # DUT linker script
│ └── model_test.h # DUT specific header file
├── riscof_spike.py # DUT python plugin
├── spike_isa.yaml # DUT ISA yaml based on riscv-config
└── spike_platform.yaml # DUT Platform yaml based on riscv-config
├──sail_cSim/ # reference plugin templates
├── env
│ ├── link.ld # Reference linker script
│ └── model_test.h # Reference model specific header file
├── init.py
└── riscof_sail_cSim.py # Reference model python plugin.

将上面的spike改为C920的plugin就可以了,当然需要修改各个配置文件和python文件
c920_isa.yaml

hart_ids: [0]
hart0:ISA: RV64IMAFDCVZicsr_Zicbom_Zicbop_Zicboz_Zihintpause_Zfh_Zca_Zcb_Zcd_Zba_Zbb_Zbc_Zbsphysical_addr_sz: 40User_Spec_Version: "2.2"Privilege_Spec_Version: "1.10"hw_data_misaligned_support: falsepmp_granularity: 4supported_xlen: [64]

c920_platform.yaml

mtime:implemented: trueaddress: 0xBFF8
mtimecmp:implemented: trueaddress: 0x4000
nmi:label: nmi_vector
reset:address: 0x000000000 

执行下面的命令,会从test_list.yaml 提取case列表跑各个case,可以注释掉其中一些,只跑部分case

riscof run --config=config.ini
–suite=riscv-arch-test/riscv-test-suite/
–env=riscv-arch-test/riscv-test-suite/env
–testfile=riscof_work/test_list.yaml

执行下面的命令会生成test_list.yaml 并且跑regression

riscof run --config=config.ini
–suite=riscv-arch-test/riscv-test-suite/
–env=riscv-arch-test/riscv-test-suite/env

10. 测试结果

在这里插入图片描述
错误原因分析:
第一种:
在这里插入图片描述
是因为编译的时候遇到错误

    INFO | Compiling test: /ssd_fes/jiongz/desktop/github/c920_riscof1/riscv-arch-test/riscv-test-suite/rv64i_m/I/src/beq-01.SERROR | /opt/picocom/ThirdParty_Libs/T-head/C920_R2S0P21/C920_R2S0_manuals_and_tools/manuals_and_tools/08_toolchain_900_series_cpu_toolchain/V2.8.0/Xuantie-900-gcc-elf-newlib-x86_64-V2.8.0/bin/../lib/gcc/riscv64-unknown-elf/10.4.0/../../../../riscv64-unknown-elf/bin/ld: main.elf section `.text' will not fit in region `MEM1'
collect2: error: ld returned 1 exit status

第二种:
在这里插入图片描述
就是c920默认没使能某个指令
在这里插入图片描述

11. rv64i_m/I/src/add-01.S 波形

model_test.h中还有一个宏,用来dump signature和finish simulation

// This will dump the test results (signature) via the testbench dump module.
#define RVMODEL_HALT                                          \signature_dump:                                           \la   a0, begin_signature;                               \la   a1, end_signature;                                 \li   a2, 0xF0000040;                                    \signature_dump_loop:                                      \bge  a0, a1, signature_dump_end;                        \lw   t0, 0(a0);                                         \sw   t0, 0(a2);                                         \addi a0, a0, 4;                                         \j    signature_dump_loop;                               \signature_dump_end:                                       \nop;                                                    \terminate_simulation:                                     \li   a0, 0xF0000000;                                    \li   a1, 0xCAFECAFE;                                    \sw   a1, 0(a0);                                         \j    terminate_simulation

对应tb.v中有

always @(posedge `CPU_CLK or negedge `CPU_RST) beginif (!`CPU_RST) beginmsi <= 1'b0;mei <= 1'b0;mti <= 1'b0;end else begin//if ((wb_cpu.cyc == 1'b1) && (wb_cpu.stb == 1'b1) && (wb_cpu.we == 1'b1) && (cpu_awaddr[31:0] == 32'hF000_0000)) beginif ((cpu_awaddr[31:0] == 32'hF000_0000) && cpu_wvalid && `clk_en && (cpu_wstrb[15:0] == 16'hf)) begincase (`SOC_TOP.biu_pad_wdata[31:0])32'hCAFE_CAFE: begin // end simulation$display("Finishing simulation.");#100;if(fail_cnt >0) begin$error("This case test failed!");end$finish;end......end// Signature Dump
int dump_file; // Declare file handle
always @(posedge `CPU_CLK) beginif ((cpu_awaddr[31:0] == 32'hF000_0040) && cpu_wvalid && `clk_en && (cpu_wstrb[15:0] == 16'hf)) beginif (!dump_file) begin // Check if file is already opendump_file = $fopen("DUT-c920.signature", "w"); // Open file if not already openedend//for (int i = 7; i >= 0; i--) begin//    $fwrite(dump_file, "%h\n", `SOC_TOP.biu_pad_wdata[i*4 +: 4]); // Write data//end$fwrite(dump_file, "%h\n", `SOC_TOP.biu_pad_wdata[31:0]); // Write dataendelse if((cpu_awaddr[31:0] == 32'hF000_0000) && cpu_wvalid && `clk_en && (cpu_wstrb[15:0] == 16'hf)) beginif (dump_file) begin // If file is open, close it$fclose(dump_file);dump_file = 0; // Reset file handle to 0 indicating file is closedendend
end// RVMODEL_IO_ASSERT_GPR_EQ(testreg, destreg, correctval) used to check destreg == correctval
// destreg != correctva write testreg 1, else write testreg 0
always @(posedge `CPU_CLK) beginif ((cpu_awaddr[31:0] == 32'hF000_0080) && cpu_wvalid && `clk_en && (cpu_wstrb[15:0] == 16'hf)) beginif(`SOC_TOP.biu_pad_wdata == 1'b1) beginfail_cnt ++;endend
end
#include "model_test.h"
#include "arch_test.h"
RVTEST_ISA("RV64I").section .text.init
.globl rvtest_entry_point
rvtest_entry_point:
RVMODEL_BOOT
RVTEST_CODE_BEGIN#ifdef TEST_CASE_1RVTEST_CASE(0,"//check ISA:=regex(.*64.*);check ISA:=regex(.*I.*);def TEST_CASE_1=True;",add)RVTEST_SIGBASE( x8,signature_x8_1)inst_0:
// rs1 == rs2 != rd, rs1==x0, rs2==x0, rd==x20, rs1_val > 0 and rs2_val > 0, rs1_val == 4, rs1_val==4 and rs2_val==6148914691236517206, rs1_val != rs2_val
// opcode: add ; op1:x0; op2:x0; dest:x20; op1val:0x0;  op2val:0x0
TEST_RR_OP(add, x20, x0, x0, 0x0, 0x0, 0x0, x8, 0, x16)inst_1:
// rs2 == rd != rs1, rs1==x2, rs2==x26, rd==x26, rs1_val > 0 and rs2_val < 0, rs2_val == -1073741825
// opcode: add ; op1:x2; op2:x26; dest:x26; op1val:0x5;  op2val:-0x40000001
TEST_RR_OP(add, x26, x2, x26, 0xffffffffc0000004, 0x5, -0x40000001, x8, 8, x16)inst_2:
// rs1 == rs2 == rd, rs1==x22, rs2==x22, rd==x22, rs1_val < 0 and rs2_val < 0, rs1_val == -8388609
// opcode: add ; op1:x22; op2:x22; dest:x22; op1val:-0x800001;  op2val:-0x800001
TEST_RR_OP(add, x22, x22, x22, 0xfffffffffefffffe, -0x800001, -0x800001, x8, 16, x16)

“riscof_work/rv64i_m/I/src/add-01.S/dut/DUT-c920.signature” 内容如下:

e7d4b281
6f5ca309
00000000
00000000
c0000004
ffffffff
fefffffe
ffffffff
ffffffbf
007fffff
00000080
00000000
66666665
e6666666
00000001
00000000
0001ffff
80000000
10000001
00000000
fffffeff

在这里插入图片描述
在这里插入图片描述

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

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

相关文章

微信小程序推送消息java版

需求背景 使用springboot2微信小程序推送消息。百度了一下看了一篇文章整体还可以&#xff0c;这里推荐一下。 教程解析 1、微信平台开通订阅消息。 2、添加模板。 3、springboot后台接口开发 微信平台验证地址接口开发&#xff0c;然后部署到公网服务器。 4、微信平台验…

基于FPGA的数字信号处理(15)--定点数的舍入模式(6)向0取整fix

前言 在之前的文章介绍了定点数为什么需要舍入和几种常见的舍入模式。今天我们再来看看另外一种舍入模式&#xff1a;向上取整fix。 10进制数的fix fix&#xff1a;也叫 向0取整。它的舍入方式是数据往0的方向&#xff0c;舍入到最近的整数&#xff0c;比如1.75 fix到2&#xf…

将WordPress的文章重新排序的3个方法

有效的调整文章显示顺序看开可以更好突出内容&#xff0c;还可以保持网站的新鲜感&#xff0c;今天我将带您了解三种方法&#xff0c;通过重新排序文章显著提升网站的吸引力。我们将逐步讲解从调整设置到使用插件以及“置顶”文章的每一种方法&#xff0c;确保WordPress 新手也…

利用python进行数据分析 —— python正则表达式(持续更新中!)

文章目录 利用python进行数据分析 —— python基础知识进阶重点笔记&#xff1a;正则表达式re.match 匹配开头re.search 全文匹配re.sub 替换删除re.compile 编译正则findall 返回列表finditer 返回迭代器re.split 分割返回列表(?P...) 分组匹配正则表达符号、修饰符通配符1 ^…

谷歌上新!最强开源模型Gemma 2,27B媲美LLaMA3 70B,挑战3140亿Grok-1

文章目录 LMSYS Chatbot Arena&#xff1a;开源模型性能第一Gemma为什么这么强&#xff1f;架构创新对AI安全性的提升 A领域竞争激烈&#xff0c;GPT-4o 和 Claude 3.5 Sonnet 持续发力&#xff0c;谷歌迅速跟进。 谷歌为应对AI竞争所采取的策略&#xff1a;依靠 Gemini 闭源模…

hdu物联网硬件实验3 按键和中断

学院 班级 学号 姓名 日期 成绩 实验题目 按键和中断 实验目的 实现闪灯功能转换 硬件原理 无 关键代码及注释 /* Button Turns on and off a light emitting diode(LED) connected to digital pin 13, when pressing a pushbutton attached…

解决WSL2报错:当前电脑配置不支持WSL2,请启用虚拟机平台 Windows 功能并确保在 BIOS 中启用虚拟化

事情要追溯到突发奇想下载了腾讯的手游模拟器开始。。。因为一直闪退&#xff0c;模拟器自检就要求把虚拟化功能关闭了&#xff0c;结果还是一直闪退&#xff0c;WSL2也给我报错了。。。大无语 主要通过以下两个步骤解决&#xff0c;操作了之后需要把电脑重启&#xff1a; 一、…

小程序做自定义分享封面图,Canvas base64图片数据真机上不显示?【已解决】

首选说一下需求&#xff0c;做一个小程序分享&#xff0c;但是封面图要自定义&#xff0c;除了要有对应商品还有有背景图&#xff0c;商品名。类似这种 实现逻辑&#xff0c;把商品图和背景图&#xff0c;再加上价格和商品名用canvas 渲染出来 这是弄好之后的效果图&#xff0…

SpringSecurity中文文档(Servlet Method Security)

Method Security 除了在请求级别进行建模授权之外&#xff0c;Spring Security 还支持在方法级别进行建模。 您可以在应用程序中激活它&#xff0c;方法是使用EnableMethodSecurity 注释任何Configuration 类&#xff0c;或者将 < method-security > 添加到任何 XML 配…

springbootAl农作物病虫害预警系统-计算机毕业设计源码21875

摘要 随着农业现代化的推进&#xff0c;农作物病虫害的防治已成为农业生产中的重要环节。传统的病虫害防治方法往往依赖于农民的经验和观察&#xff0c;难以准确、及时地预测和防控病虫害的发生。因此&#xff0c;开发一种基于现代信息技术的农作物病虫害预警系统&#xff0c;对…

【计算机毕业设计】012基于微信小程序的科创微应用平台

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…

解决vite 断点调试定位不准确问题

问题&#xff1a;vite构建时&#xff0c;控制台报错行数等信息定位不准确或debugger断点调试定位不准确 解决&#xff1a;F12后打开设置面板&#xff0c;把“JavaScript源代码映射”去掉可临时解决&#xff0c;如需永久解决需升级vite到最新版 还有一种&#xff1a; 参考&…

7.9 cf div3

BProblem - B - Codeforces 题目解读&#xff1a; 找到严格大于相邻数字的数&#xff0c;将其减一&#xff0c;直到整个数组成为稳定的&#xff08;不存在数字严格大于相邻数&#xff09; ac代码 #include<bits/stdc.h> typedef long long ll;#define IOS ios::sync_w…

免费白嫖A100活动开始啦,InternLM + LlamaIndex RAG 实践

内容来源&#xff1a;Docs 前置知识&#xff1a; 检索增强生成&#xff08;Retrieval Augmented Generation&#xff0c;RAG&#xff09; LlamaIndex LlamaIndex 是一个上下文增强的 LLM 框架&#xff0c;旨在通过将其与特定上下文数据集集成&#xff0c;增强大型语言模型&a…

决策树算法简单介绍:原理和方案实施

决策树算法介绍&#xff1a;原理和方案实施 决策树&#xff08;Decision Tree&#xff09;是一种常用的机器学习算法&#xff0c;它既可以用于分类任务&#xff0c;也可以用于回归任务。由于其直观性和解释性&#xff0c;决策树在数据分析和模型构建中得到了广泛的应用。本文将…

顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶

欢迎关注博主 Mindtechnist 或加入【智能科技社区】一起学习和分享Linux、C、C、Python、Matlab&#xff0c;机器人运动控制、多机器人协作&#xff0c;智能优化算法&#xff0c;滤波估计、多传感器信息融合&#xff0c;机器学习&#xff0c;人工智能等相关领域的知识和技术。关…

挖K脚本检测指南

免责声明:本文仅做分享... 目录 挖K样本-Win&Linux-危害&定性 Linux-Web 安全漏洞导致挖K事件 Windows-系统口令爆破导致挖K事件 --怎么被挖K了??? 已经取得了权限. 挖K样本-Win&Linux-危害&定性 危害&#xff1a;CPU 拉满&#xff0c;网络阻塞&…

在Linux下使用Docker部署chirpstack

目录 一、前言 二、chirpstack 1、chirpstack是什么 2、chirpstack组件 3、为什么选择Docker部署 三、Linux下部署过程 四、web界面部署过程 一、前言 本篇文章我是在Linux下使用 Docker 进行部署chirpstack&#xff0c;chirpstack采用的是v4 版本&#xff0c;v4 版本 与…

Logstash常用的filter四大插件

以博客<ELK日志分析系统概述及部署>中实验结果为依据 补充&#xff1a;如何用正则表达式匹配一个ipv4地址 &#xff08;[0-9] | [1-9][0-9] | 1[0-9][0-9] | 2[04][0-9] | 25[0-5]&#xff09;\.&#xff08;[0-9] | [1-9][0-9] | 1[0-9][0-9] | 2[04][0-9] | 25[0-5]&a…

基于Java的数码论坛系统设计与实现

你好&#xff0c;我是计算机领域的研究者。如果你对数码论坛系统开发感兴趣或有相关需求&#xff0c;欢迎联系我。 开发语言&#xff1a; Java 数据库&#xff1a; MySQL 技术&#xff1a; Java技术、MySQL数据库、B/S架构、SpringBoot框架 工具&#xff1a; Eclipse、MySQ…