내 연락처 정보
우편메소피아@프로톤메일.com
2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
riscv-arch-test에 직접적으로 초점을 맞추는 이유는 RISCOF 테스트 프레임워크가 riscv-arch-test를 사용하기 때문입니다.
아키텍처 테스트는 컴파일하고 실행할 수 있는 가장 작은 테스트 코드를 나타내는 단일 테스트입니다. 어셈블리 코드로 작성되었으며 해당 제품은 테스트 서명입니다. 아키텍처 테스트는 여러 테스트 케이스로 구성될 수 있습니다.
RISC-V 아키텍처 테스트 풀은 테스트 프레임워크를 통해 아키텍처 테스트 스위트로 컴파일될 수 있는 승인된 모든 아키텍처 테스트로 구성됩니다. RISC-V 아키텍처 테스트 라이브러리는 테스트 대상에 구애받지 않아야 합니다. 따라서 모든 호환 대상에서 올바르게 실행되어야 합니다. 이 비기능 테스트는 검증 또는 장치 테스트를 대체할 수 없습니다.
architectural-tests-suite (root)
|-- <architecture>_<mode>/<feature(s)>, where
<architecture> is [ RV32I | RV64I | RV32E ]
<mode> is [ M | MU | MS | MSU ], where
M Machine mode tests - tests execute in M-mode only
MU 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)
미사 = 0x800000000094112f
이진 표현: 100000000000000000000000000000000000000100101000001000100101111
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/ 특권/ P_비준되지 않음/ Zfh/ Zfinx/ Zicond/ Zifencei/
RISC-V 아키텍처 테스트 스위트는 특정 RISC-V 구성의 적합성을 테스트하기 위해 아키텍처 테스트 풀에서 선택된 테스트 세트입니다. 테스트 결과는 테스트 스위트 서명의 형태로 얻어집니다. 테스트 선택은 대상의 어설션 구성, 사양, 실행 환경 또는 플랫폼 요구 사항을 기반으로 합니다. 호환 프로세서 또는 프로세서 모델은 테스트 중인 특정 구성과 동일한 Gold Reference Test Suite 서명을 표시해야 합니다.
테스트 케이스는 아키텍처 테스트의 일부이며 사양의 한 가지 기능만 테스트합니다.
참고: 테스트에는 여러 테스트 사례가 포함될 수 있으며 각 테스트 사례에는 자체 테스트 포함 조건(RVTEST_CASE 매크로의 cond_str 매개변수로 정의됨)이 있습니다.
<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
//
// 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_1
RVTEST_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_HALT
RVTEST_DATA_BEGIN
.align 4
rvtest_data:
.word 0xbabecafe
.word 0xbabecafe
.word 0xbabecafe
.word 0xbabecafe
RVTEST_DATA_END
RVMODEL_DATA_BEGIN
rvtest_sig_begin:
sig_begin_canary:
CANARY;
signature_x3_0:
.fill 0*(XLEN/32),4,0xdeadbeef
signature_x3_1:
.fill 17*(XLEN/32),4,0xdeadbeef
signature_x8_0:
.fill 16*(XLEN/32),4,0xdeadbeef
signature_x1_0:
.fill 512*(XLEN/32),4,0xdeadbeef
signature_x1_1:
.fill 43*(XLEN/32),4,0xdeadbeef
#ifdef rvtest_mtrap_routine
tsig_begin_canary:
CANARY;
mtrap_sigptr:
.fill 64*(XLEN/32),4,0xdeadbeef
tsig_end_canary:
CANARY;
#endif
#ifdef rvtest_gpr_save
gpr_save:
.fill 32*(XLEN/32),4,0xdeadbeef
#endif
sig_end_canary:
CANARY;
rvtest_sig_end:
RVMODEL_DATA_END
위 어셈블리 코드에 대한 간략한 설명은 다음과 같습니다.
# 이 어셈블리 파일은 add 커버그룹에 대한 RISC-V I 확장의 add 명령어를 테스트합니다.
#include “model_test.h”
#include “arch_test.h”
각 테스트에는 다음 헤더 파일만 포함되어야 합니다.
model_test.h - 필수 및 선택적 매크로를 포함하여 대상별 매크로를 정의합니다. (예: RVMODEL_xxx)
Arch_test.h - 필수 매크로 및 선택적 매크로를 포함하여 사전 정의된 테스트 매크로를 정의합니다(예: RVTEST_xxx).
RVTEST_ISA(“RV32I”)
RV모델_부트
RVTEST_CODE_BEGIN
테스트 케이스 1
// 이 테스트는 rv32I 확장을 구현하는 장치를 위한 것이며 컴파일을 활성화해야 합니다.
// 매크로 TEST_CASE_1. 이 테스트는 "add" 커버리지 라벨에 기여합니다.
RVTEST_CASE(0,“//ISA:=regex(확인하세요.32.);ISA:=regex(을 확인하세요.나.);def TEST_CASE_1=참;”,추가)
RVTEST_SIGBASE(x16,signature_x16_1) // x16은 signature 영역의 signature_x16_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)
...
...
//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+REGWIDTH
RVMODEL_IO_ASSERT_GPR_EQ 定义在target的model_test.h中```
在咱们得model_test.h中将RVMODEL_IO_ASSERT_GPR_EQ 宏定义如下:比较错误的话,往0xF0000080写1
```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) begin
if ((cpu_awaddr[31:0] == 32'hF000_0080) && cpu_wvalid && `clk_en && (cpu_wstrb[15:0] == 16'hf)) begin
if(`SOC_TOP.biu_pad_wdata == 1'b1) begin
fail_cnt ++;
end
end
end
// 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)
...
...
RVTEST_CODE_END
RVMODEL_HALT
RVTEST_DATA_BEGIN
rvtest_data:
.word 0xbabecafe
RVTEST_DATA_END
RVMODEL_DATA_BEGIN
rvtest_sig_begin:
sig_begin_canary:
CANARY;
signature_x3_0:
.fill 0*(XLEN/32),4,0xdeadbeef
signature_x3_1:
.fill 17*(XLEN/32),4,0xdeadbeef
signature_x8_0:
.fill 16*(XLEN/32),4,0xdeadbeef
signature_x1_0:
.fill 512*(XLEN/32),4,0xdeadbeef
signature_x1_1:
.fill 43*(XLEN/32),4,0xdeadbeef
#ifdef rvtest_mtrap_routine
tsig_begin_canary:
CANARY;
mtrap_sigptr:
.fill 64*(XLEN/32),4,0xdeadbeef
tsig_end_canary:
CANARY;
#endif
#ifdef rvtest_gpr_save
gpr_save:
.fill 32*(XLEN/32),4,0xdeadbeef
#endif
sig_end_canary:
CANARY;
rvtest_sig_end:
RVMODEL_DATA_END
테스트 케이스 서명은 단일 또는 다중 값으로 표시됩니다. 값은 RVMODEL_DATA_BEGIN에 지정된 주소에서 시작하여 RVMODEL_DATA_END에 지정된 주소에서 끝나는 메모리에 기록됩니다. 서명은 RVTEST_SIGUPD 매크로를 사용하여 쉽게 생성됩니다.
테스트 서명은 아키텍처 테스트 실행으로 생성된 특성 값입니다. 테스트 서명은 여러 테스트 케이스 서명으로 구성될 수 있으며, 앞에는 테스트 이름과 해당 버전을 나타내는 고유 값이 포함된 별도의 줄이 추가됩니다. 테스트 대상은 RVMODEL_DATA_BEGIN 및 RVMODEL_DATA_END 매크로를 사용하여 프레임워크에서 제공하는 메타데이터를 사용하여 메모리에서 값을 추출하고 적절하게 형식화하는 작업을 담당합니다.테스트 케이스 서명 값은 왼쪽의 최상위 바이트부터 시작하여 다음 형식으로 행에 기록됩니다.<hex_value> 여기서 값의 길이는 32비트(8자)이지만 실제 테스트 계산에서는 값의 길이를 고려하지 않습니다. 파일은 서명의 가장 낮은 주소 값부터 시작하여(즉, RVMODEL_DATA_BEGIN부터 RVMODEL_DATA_END까지) 저장되어야 합니다. 또한 서명은 항상 16바이트(128비트) 경계에서 시작해야 하며 서명 크기는 4바이트의 배수여야 합니다(즉, 4바이트 경계에서 끝나야 함).
테스트 스위트 서명은 주어진 아키텍처 테스트 스위트에 유효한 테스트 서명 세트로 정의됩니다. 이는 특정 RISC-V 구성을 위해 선택된 아키텍처 테스트 스위트의 테스트 서명을 나타냅니다.
RISCOF - RISC-V 호환성 프레임워크는 RISC-V 아키텍처 테스트 세트 세트를 사용하여 표준 RISC-V Golden Reference와의 호환성을 위해 RISC-V 대상(하드웨어 또는 소프트웨어 구현)을 테스트할 수 있는 Python 기반 프레임워크입니다. 모델섹스.
RISC-V 구성 검증기 : RISCV-Config
RISC-V 컴플라이언스 테스트 생성기 : RISC-V CTG
RISC-V ISA 적용 범위 : RISC-V ISAC
RISCOF가 정상적으로 테스트를 진행하기 위해서는 다음과 같은 내용이 제공되어야 합니다.
$ riscof 설정 --dutname=스파이크
위 명령은 현재 디렉터리에 다음 파일과 디렉터리를 생성합니다.
├──config.ini # riscof에 대한 설정 파일
├──spike/ # DUT 플러그인 템플릿
├── 환경
│ ├── link.ld # DUT 링커 스크립트
│ └── model_test.h # DUT 특정 헤더 파일
├── riscof_spike.py # DUT 파이썬 플러그인
├── spike_isa.yaml # riscv-config 기반 DUT ISA yaml
└── spike_platform.yaml # riscv-config 기반 DUT 플랫폼 yaml
├──sail_cSim/ # 참조 플러그인 템플릿
├── 환경
│ ├── link.ld # 참조 링커 스크립트
│ └── model_test.h # 참조 모델 특정 헤더 파일
├── 초기화.파이
└── riscof_sail_cSim.py # 참조 모델 파이썬 플러그인.
위의 스파이크를 C920 플러그인으로 변경하면 됩니다. 물론 각 구성 파일과 Python 파일을 수정해야 합니다.
c920_isa.yaml
hart_ids: [0]
hart0:
ISA: RV64IMAFDCVZicsr_Zicbom_Zicbop_Zicboz_Zihintpause_Zfh_Zca_Zcb_Zcd_Zba_Zbb_Zbc_Zbs
physical_addr_sz: 40
User_Spec_Version: "2.2"
Privilege_Spec_Version: "1.10"
hw_data_misaligned_support: false
pmp_granularity: 4
supported_xlen: [64]
c920_플랫폼.yaml
mtime:
implemented: true
address: 0xBFF8
mtimecmp:
implemented: true
address: 0x4000
nmi:
label: nmi_vector
reset:
address: 0x000000000
다음 명령을 실행하면 test_list.yaml에서 사례 목록이 추출되고 각 사례가 실행됩니다. 일부 사례를 주석 처리하고 일부 사례만 실행할 수 있습니다.
riscof 실행 --config=config.ini
–suite=riscv-arch-test/riscv-테스트-수트/
–env=riscv-arch-test/riscv-테스트-수트/env
–테스트파일=리스코프_워크/테스트_리스트.yaml
다음 명령을 실행하면 test_list.yaml이 생성되고 회귀가 실행됩니다.
riscof 실행 --config=config.ini
–suite=riscv-arch-test/riscv-테스트-수트/
–env=riscv-arch-test/riscv-테스트-수트/env
오류 원인 분석:
첫번째:
컴파일 중에 오류가 발생했기 때문입니다.
INFO | Compiling test: /ssd_fes/jiongz/desktop/github/c920_riscof1/riscv-arch-test/riscv-test-suite/rv64i_m/I/src/beq-01.S
ERROR | /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은 기본적으로 특정 명령을 활성화하지 않습니다.
덤프 서명 및 시뮬레이션 완료를 위한 매크로도 model_test.h에 있습니다.
// 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) begin
if (!`CPU_RST) begin
msi <= 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)) begin
if ((cpu_awaddr[31:0] == 32'hF000_0000) && cpu_wvalid && `clk_en && (cpu_wstrb[15:0] == 16'hf)) begin
case (`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) begin
if ((cpu_awaddr[31:0] == 32'hF000_0040) && cpu_wvalid && `clk_en && (cpu_wstrb[15:0] == 16'hf)) begin
if (!dump_file) begin // Check if file is already open
dump_file = $fopen("DUT-c920.signature", "w"); // Open file if not already opened
end
//for (int i = 7; i >= 0; i--) begin
// $fwrite(dump_file, "%hn", `SOC_TOP.biu_pad_wdata[i*4 +: 4]); // Write data
//end
$fwrite(dump_file, "%hn", `SOC_TOP.biu_pad_wdata[31:0]); // Write data
end
else if((cpu_awaddr[31:0] == 32'hF000_0000) && cpu_wvalid && `clk_en && (cpu_wstrb[15:0] == 16'hf)) begin
if (dump_file) begin // If file is open, close it
$fclose(dump_file);
dump_file = 0; // Reset file handle to 0 indicating file is closed
end
end
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) begin
if ((cpu_awaddr[31:0] == 32'hF000_0080) && cpu_wvalid && `clk_en && (cpu_wstrb[15:0] == 16'hf)) begin
if(`SOC_TOP.biu_pad_wdata == 1'b1) begin
fail_cnt ++;
end
end
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_1
RVTEST_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"의 내용은 다음과 같습니다.
이7d4b281
6f5ca309
00000000
00000000
c0000004
프프프프프
페프프프
프프프프프
프프프프프프
007fffff
00000080
00000000
66666665
e6666666
00000001
00000000
0001ffff
80000000
10000001
00000000
프프프프프